缓冲思想
字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想(装饰模式),所以提供了字节缓冲区流。
缓冲输入流BufferedInputStream
BufferedInputStream内置了一个缓冲区(数组),从BufferedInputStream中读取一个字节时,BufferedInputStream会一次性从文件中读取8192个, 存在缓冲区中, 返回给程序一个字节,程序再次读取时, 就不用找文件了, 直接从缓冲区中获取第2个字节,依次类推,直到缓冲区中所有的都被使用过, 再重新从文件中读取8192个
缓冲输出流BufferedOutputStream
BufferedOutputStream也内置了一个缓冲区(数组),程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中,直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里。
使用缓冲流COPY文件
@Testpublic void demo1() throws FileNotFoundException, IOException {FileInputStream fis = new FileInputStream("孤勇者.mp3"); //创建输入流对象,关联致青春.mp3FileOutputStream fos = new FileOutputStream("孤勇者copy4.mp3"); //创建输出流对象,关联copy.mp3BufferedInputStream bis = new BufferedInputStream(fis); //创建缓冲区对象,对输入流进行包装让其变得更加强大BufferedOutputStream bos = new BufferedOutputStream(fos);int b;while((b = bis.read()) != -1) {bos.write(b);}bis.close();bos.close();}
当循环第一次时,发现缓冲区是空的,会一次从文件中读取8192个字节(查看源码可知,默认),并且返回第一个字节数据,我们手动将其写入到缓冲输出流
当循环第二次时,发现缓冲区还存在未使用的字节,就把缓冲区的第2个字节,直接返回,我们再手动写入缓冲输出流中。
依此类推
当缓冲区所有字节都被返回后,它会再从文件中获取第二批数据(8192个字节),循环往复,直到读取完所有输入流中的数据,返回-1时,结束。
缓冲输出流内部缓冲区8192个字节(查看源码可知,默认)被写满时,会将这一批一次性写入输出流中(文件)
虽然每次循环返回1个字节,再写入1个字节,但这都是在内存中完成的,效率还是非常快的。
而从硬盘读取数据和写入数据到硬盘的环节,相比非缓冲输入流和非缓冲输出流已经减少了读写次数。
思考
定义8192字节的小数组的读写和带Buffered的读取哪个更快?
答:定义小数组如果是8192个字节大小和Buffered比较的话,定义小数组会略胜一筹,因为读和写操作的是同一个数组,而Buffered操作的是两个数组
