前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BufferedInputStream 缓冲区原理解析

BufferedInputStream 缓冲区原理解析

作者头像
java404
发布2018-05-18 11:55:01
9000
发布2018-05-18 11:55:01
举报
文章被收录于专栏:java 成神之路java 成神之路

BufferedInputStream是带缓冲区的输入流,默认缓冲区大小是8M,能够减少访问磁盘的次数,提高文件读取性能;BufferedOutputStream是带缓冲区的输出流,能够提高文件的写入效率。BufferedInputStream与BufferedOutputStream分别是FilterInputStream类和FilterOutputStream类的子类,实现了装饰设计模式。

BufferedInputStream在其内部维护一个字节数组作为缓冲区,而从底层(文件)流中读取数据的操作还是调用InputStream的方法完成。

下面通过一个例子来讲解Buffered的缓冲区原理机制

代码语言:javascript
复制
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:1
            System.out.println("Char : " + (char) bis.read());    //step:2

            bis.mark(3);                                          //step:3
            System.out.println("-------mark(3)----------");

            System.out.println("Char : " + (char) bis.read());    //step:4
            System.out.println("Char : " + (char) bis.read());    //step:5
            System.out.println("Char : " + (char) bis.read());    //step:6

            bis.reset();                                          //step:7
            System.out.println("-------reset()----------");

            int b;
            while ((b = bis.read()) != -1) {
                System.out.println("char : " + (char) b);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出的结果为:

代码语言:javascript
复制
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()**

read()操作

第一次读取数据,首先初始化一个4字节大小的缓冲区,然后调用内部的fill()方法填充缓冲区,填充完成后开始读取缓冲区中的第一个元素“1”。 程序通过i++操作读取完第一个数据后pos坐标就会指向下一个待读取的元素(这里指向第二个元素)。

数组坐标是从0开始的,所以读取完成第一个元素后,pos=1。

pos=1

step:2

操作:read()

read()操作

读出元素“2”

pos=2

step:3

操作:mark (3)

reset(3)操作

执行mark(3)进行标记。这时markpos和pos坐标相同.

markpos=2 pos=2

step:4

** 操作:read()**

read()操作

读出元素“3”

markpos=2 pos=3

step:5

** 操作:read()**

read()操作

读出元素“4”

markpos=2 pos=4

step:6

** 操作:read()**

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()操作

reset()后把pos的坐标置为0,然后在读取的时候又可以读取到元素“3、4、5”

后续while循环操作

read()操作

读取元素“3”、“4”、“5”时坐标的变化

后续while循环操作

read()操作

读取元素“6”

markpos=0 pos=4

注意:这时如果执行reset操作,那么将可以读取之前的4个元素(mark(3)的时候指定的是可以读取3个元素)

后续while循环操作

read()操作

缓冲区读完后,重新再读取一批数据,因为该缓冲区没有执行mark操作,此时设置markpos=-1。

最后一次读取

read()操作

读取元素“0”


本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.07.21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 准备
  • 变量说明:
  • step:1
  • step:2
  • step:3
  • step:4
  • step:5
  • step:6
  • step:7
  • 后续while循环操作
    • 后续while循环操作
      • 后续while循环操作
        • 最后一次读取
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档