BufferedInputStream 缓冲区原理解析
BufferedInputStream是带缓冲区的输入流,默认缓冲区大小是8M,能够减少访问磁盘的次数,提高文件读取性能;BufferedOutputStream是带缓冲区的输出流,能够提高文件的写入效率。BufferedInputStream与BufferedOutputStream分别是FilterInputStream类和FilterOutputStream类的子类,实现了装饰设计模式。
BufferedInputStream在其内部维护一个字节数组作为缓冲区,而从底层(文件)流中读取数据的操作还是调用InputStream的方法完成。
下面通过一个例子来讲解Buffered的缓冲区原理机制
public class BufferedInputStreamDemo {public static void main(String[] args) throws Exception {try (InputStream ai = new ByteArrayInputStream("1234567890".getBytes());InputStream bis = new BufferedInputStream(ai, 4)) {System.out.println("Char : " + (char) bis.read()); //step:1System.out.println("Char : " + (char) bis.read()); //step:2bis.mark(3); //step:3System.out.println("-------mark(3)----------");System.out.println("Char : " + (char) bis.read()); //step:4System.out.println("Char : " + (char) bis.read()); //step:5System.out.println("Char : " + (char) bis.read()); //step:6bis.reset(); //step:7System.out.println("-------reset()----------");int b;while ((b = bis.read()) != -1) {System.out.println("char : " + (char) b);}} catch (Exception e) {e.printStackTrace();}} }输出的结果为:
Char : 1 Char : 2 -------mark(3)---------- Char : 3 Char : 4 Char : 5 -------reset()---------- char : 3 char : 4 char : 5 char : 6 char : 7 char : 8 char : 9 char : 0准备
构造一个BufferedInputStream对象,缓冲区的大小为4字节。从ByteArrayInputStream流中读取数据“1234567890”。
变量说明:
pos:是下一次待读取缓冲区的坐标
markpos:mark()标记的缓冲区坐标。默认markpos=-1。
step:1
* 操作:read()*
第一次读取数据,首先初始化一个4字节大小的缓冲区,然后调用内部的fill()方法填充缓冲区,填充完成后开始读取缓冲区中的第一个元素“1”。
程序通过i++操作读取完第一个数据后pos坐标就会指向下一个待读取的元素(这里指向第二个元素)。
数组坐标是从0开始的,所以读取完成第一个元素后,pos=1。
pos=1
step:2
操作:read()
读出元素“2”
pos=2
step:3
操作:mark (3)
执行mark(3)进行标记。这时markpos和pos坐标相同.
markpos=2
pos=2
step:4
* 操作:read()*
读出元素“3”
markpos=2
pos=3
step:5
* 操作:read()*
读出元素“4”
markpos=2
pos=4
step:6
* 操作:read()*
当读取pos=4时,超出缓冲区容量,这时,需要重新再从目标流中读取元素。因为在step:3时mark标记过元素,当reset的时候还需要读取(元素“3和4”)。这时,需要把mark后的元素也要保留到缓冲区中,mark之前的数据丢弃(元素“1和2”)。剩下的容量读取新元素(还可读取两个元素“5、和6”)。
标记过的元素“3”的坐标现在为0。所以markpos=0。
读出元素“5”
markpos=0
pos=4
step:7
* 操作:reset()*
reset()后把pos的坐标置为0,然后在读取的时候又可以读取到元素“3、4、5”
后续while循环操作
读取元素“3”、“4”、“5”时坐标的变化
后续while循环操作
读取元素“6”
markpos=0
pos=4
注意:这时如果执行reset操作,那么将可以读取之前的4个元素(mark(3)的时候指定的是可以读取3个元素)
后续while循环操作
缓冲区读完后,重新再读取一批数据,因为该缓冲区没有执行mark操作,此时设置markpos=-1。
最后一次读取
读取元素“0”
本人简书blog地址:http://www.jianshu.com/u/1f0067e24ff8
点击这里快速进入简书
GIT地址:http://git.oschina.net/brucekankan/
点击这里快速进入GIT
总结
以上是生活随笔为你收集整理的BufferedInputStream 缓冲区原理解析的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: ExecutorCompletionSe
- 下一篇: 多文件同时读写为什么没有单文件读写快?