听说BufferedInputStream有缓冲区,所以效率高,可是InputStream也有呀,
差距体现在哪里?
又遇见你了。我说下自己的理解吧。FileInputStream,直接操作本机I/O,把持着一个文件的句柄,说白了它是面向文件的。而且BufferedInputStream,它只是面向字节流的,你可以不使用它,自己创建数组,将字节放在里面,也就缓存在jvm内存里,之后操作内存数据,你说快不快。而jdk给我们实现了这个方法,就像其他人说的装饰模式,在传统IO流中,体现的淋漓尽致。不仅如此,它简化了我们的代码,主要的是它是线程安全的,他通过volatile、synchronized、原子更新器 等关键字和控制,实现了线程的相对安全,这样来看的话,你可以把这个文件缓存到非局部变量中。说到底你必须使用Buffered的吗,并不是,如果你在乎代码的优化程度和安全性,完全可以用常规写法。
这个是jdk自身实现的装饰者模式,其实说到底就是对InputStream的包装,有空的话,可以看一下Head First设计模式,第三章吧,记不清了,有讲。0.0
BufferedInputStream是套在某个其他的InputStream外,起着缓存的功能,用来改善里面那个InputStream的性能(如果可能的话),它自己不能脱离里面那个单独存在。FileInputStream是读取一个文件来作InputStream。所以你可以把BufferedInputStream套在FileInputStream外,来改善FileInputStream的性能。
FileInputStream与BufferedInputStream区别:
FileInputStream是字节流,BufferedInputStream是字节缓冲流,使用BufferedInputStream读资源比FileInputStream读取资源的效率高(BufferedInputStream的read方法会读取尽可能多的字节),且FileInputStream对象的read方法会出现阻塞;
FileInputStream与FileReader区别:
FileInputStream是字节流,FileReader是字符流,用字节流读取中文的时候,可能会出现乱码,而用字符流则不会出现乱码,而且用字符流读取的速度比字节流要快;
ObjectOutputStream与ByteArrayOutputStream的区别:
ObjectOutputStream可以将java对象写入outputstream流中(序列化),然后进行持久化,此对象必须是实现了java.io.Serializable 接口;
ByteArrayOutputStream是将数据写入byte数组中;
简单说一下阻塞:
假设一个文件的长度是100个字节,要将之读取到内存中,再假设您每次只读取10个字节,那么读完整个文件是不是读取10次的呀?
假设老板让你完成100件事情,老板说,你每天只完成10件就可以了,难道你非得等到第十天才完成第100件事情吗?有一天您在中午下班前就完成了10件事情,下午您不妨多干一点,那么也许在第9天的时候就完成了100件事情。
同理,BufferedInputStream有可能会读取比您规定的更多的东西到内存,以减少访问IO的次数。简单点说阻塞就是你有能力办某一件事,但是,迫于其他压力或什么只能干等着每次只干固定的事,会浪费资源从而造成阻塞。
FileInputStream 与 BufferedInputStream 的效率对比:
我们采用文件复制来做效率对比的实验。
在FileOperator类的copyWithFileStream方法实现了使用FileInputStream和FileOutputStream复制文件,copyWithBufferedStream方法实现了使用BufferedInputStream和BufferedOutputStream复制文件。
一个是包装流,一个是节点流
FileInputStream & FileOutputStream 和 BufferedInputStream & BufferedOutputStream 都能完成文件的读写。它们在原理上、时间效率上有什么不同,
/*
package utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
@version 0
*/
public class FileOperator {
/** buffer size in bytes */
final static int BUFFER_SIZE = 100;
/**
@return;
*/
public static void copyWithFileStream(File src, File dest){
FileInputStream input = null;
FileOutputStream output = null;
try {
input = new FileInputStream(src);
output = new FileOutputStream(dest);
byte[] buffer = new byte[BUFFER_SIZE];
int copySize;
while ((copySize = input.read(buffer)) > 0){
output.write(buffer, 0, copySize);
output.flush();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
input.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
@return;
*/
public static void copyWithBufferedStream(File src, File dest){
BufferedInputStream bufferedInput = null;
BufferedOutputStream bufferedOutput = null;
try {
bufferedInput = new BufferedInputStream(new FileInputStream(src));
bufferedOutput = new BufferedOutputStream(new FileOutputStream(dest));
byte[] buffer = new byte[BUFFER_SIZE];
int copySize;
while ((copySize = bufferedInput.read(buffer)) > 0){
bufferedOutput.write(buffer, 0, copySize);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bufferedInput.close();
bufferedOutput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class FileOperatorTest{
public static void main(String args[]){
File src = new File("test.txt");
File dest = new File("copyTest.txt");
try {
if (!dest.exists()){
dest.createNewFile();
}
} catch (IOException e) {
e.printStackTrace();
}
//test copy using FileStream
int startTime = System.currentTimeMillis();
FileOperator.copyWithFileStream(src, dest);
int endTime = System.currentTimeMillis();
System.out.println("Copy file using FileStream takes : " + (endTime - startTime) + " ms.");
//test copy using BufferedStream
startTime = System.currentTimeMillis();
FileOperator.copyWithBufferedStream(src, dest);
endTime = System.currentTimeMillis();
System.out.println("Copy file using BufferedStream takes : " + (endTime - startTime) + " ms.");
}
}