Java缓冲流的作用详解
缓冲流概述
缓冲流,也叫高效流,是对4个基本的`FileXxx` 流的增强,所以也是4个流,按照数据类型分类
通过定义数组的方式确实比以前一次读取一个字节的方式快很多,所以,看来有一个缓冲区还是非常 好的。
既然是这样的话,那么,java开始在设计的时候,它也考虑到了这个问题,就专门提供了带缓冲区的字节类。
这种类被称为:缓冲区类(高效类)
写数据:BufferedOutputStream
读数据:BufferedInputStream
构造方法可以指定缓冲区的大小,但是我们一般用不上,因为默认缓冲区大小就足够了。
为什么不传递一个具体的文件或者文件路径,而是传递一个OutputStream对象呢?
原因很简单,字节缓冲区流仅仅提供缓冲区,为高效而设计的。但是呢,真正的读写操作还得靠基本 的流对象实现。
缓冲流的基本原理
创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率
字节缓冲流
public BufferedInputStream(InputStream in) | 创建一个 新的缓冲输入流。 |
---|---|
public BufferedOutputStream(OutputStream out) | 创建一个新的缓冲输出流。 |
字符缓冲流
public BufferedReader(Reader in) | 创建一个 新的缓冲输入流。 |
---|---|
public BufferedWriter(Writer out) | 创建一个新的缓冲输出流。 |
大家应该知道,在字节缓冲流之前,有普通的字节流和字符流,这里引入缓冲流是干什么呢?
下来用代码进行解释
该代码块我使用了一个24.7M大小的视频文件进行复制,从普通字节流单字节复制、普通字节流数组方式复制,缓冲流单字节复制、缓冲流数组方式复制,并将所运行时间放在后面发现,普通字节流单字节复制和缓冲流单字节复制相比,缓冲流的速度是普通字节流的1/205;普通字节流数组方式复制和缓冲流数组方式复制相比,缓冲流的速度是普通字节流的1/5,这样的速度差距清晰明了,这就是引入缓冲流的原因。
public static void main(String[] args) throws IOException {
//开始时间
long StartTime=System.currentTimeMillis();
//方法一:普通字节流单节复制文件
mothed1("E:\\面试题\\面试题视频\\10.HashMap和Hashtable的面试题.mp4","10.复制的面试题1.mp4");//128670ms
//方法二:普通字节流数组复制文件
//mothed2("E:\\面试题\\面试题视频\\10.HashMap和Hashtable的面试题.mp4","10.复制的面试题2.mp4");//171ms
//方法三:缓冲流单节复制文件
//mothed3("E:\\面试题\\面试题视频\\10.HashMap和Hashtable的面试题.mp4","10.复制的面试题3.mp4");//625ms
//方法四:缓冲流数组复制文件
//mothed4("E:\\面试题\\面试题视频\\10.HashMap和Hashtable的面试题.mp4","10.复制的面试题4.mp4");//38ms
//结束时间
long EndTime=System.currentTimeMillis();
//耗费时间
long Time=EndTime-StartTime;
System.out.println("所耗费的时间为:"+Time+"ms");
}
public static void mothed1(String a,String b) throws IOException {
//方法一:普通字节流单节复制文件
FileInputStream file=new FileInputStream(a);
FileOutputStream file1=new FileOutputStream(b);
int read;
while((read=file.read())!=-1){
file1.write(read);
}
file.close();
file1.close();
}
public static void mothed2(String a,String b) throws IOException {
FileInputStream file=new FileInputStream(a);
FileOutputStream file1=new FileOutputStream(b);
byte[] by=new byte[1024];
int len;
while((len=file.read(by))!=-1){
file1.write(by);
}
file.close();
file1.close();
}
public static void mothed3(String a,String b) throws IOException {
BufferedInputStream file=new BufferedInputStream(new FileInputStream(a));
BufferedOutputStream file1=new BufferedOutputStream(new FileOutputStream(b));
int read;
while((read=file.read())!=-1){
file1.write(read);
}
file.close();
file1.close();
}
public static void mothed4(String a,String b) throws IOException {
BufferedInputStream file=new BufferedInputStream(new FileInputStream(a));
BufferedOutputStream file1=new BufferedOutputStream(new FileOutputStream(b));
byte[] by=new byte[1024];
int len;
while((len=file.read(by))!=-1){
file1.write(by);
}
file.close();
file1.close();
}
那么,缓冲流为什么会达到这么快?
接下来进入BufferedInputStream的源码进行探索:
在这里插入图片描述
可以发现,源码中,赋予了BufferedInputStream一块8192大小的缓冲区。在文件复制的过程中,会先将文件的内容放置进缓冲区中,一次所处理的量比普通字节流相比打太多了,所以在复制文件时所消耗的时间少。