Java IO-BufferedInputStream

来源:互联网 发布:网络语蛋炒饭 编辑:程序博客网 时间:2024/06/05 06:01

BufferedInputStream 是一个带有缓冲区的输入流。缓冲区你可以理解为缓存,就像我们从数据库中读数据和从缓存中读数据同样的道理,目的都是为了能够加快读取速度。
本篇只关注如下图红框的部分
这里写图片描述

//默认缓冲区大小为8192个字节 即8k private static int DEFAULT_BUFFER_SIZE = 8192; //缓冲区最大大小 超出将报OutOfMemoryError错误 private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; //缓冲区字节数组  即我们认为的缓存组件 protected volatile byte buf[]; //初始化 public BufferedInputStream(InputStream in) {        this(in, DEFAULT_BUFFER_SIZE);    }    //初始化 可自定义缓冲区大小 public BufferedInputStream(InputStream in, int size) {        super(in);        if (size <= 0) {            throw new IllegalArgumentException("Buffer size <= 0");        }        buf = new byte[size];    }    //读取数据    public synchronized int read() throws IOException {    //pos为当前缓冲区下一个读取位置 count为缓冲区数据真实长度    //当缓冲区已经没有数据        if (pos >= count) {        //将数据读取到缓冲区            fill();            if (pos >= count)                return -1;        }        //读取缓冲区数据        return getBufIfOpen()[pos++] & 0xff;    }        private void fill() throws IOException {、        //当前缓冲区数组        byte[] buffer = getBufIfOpen();        // 默认情况下 markpos =-1 (markpos为pos的一个标记 用于重读数据,通过mark方法调用)也即 此时pos恢复到起始值        if (markpos < 0)            pos = 0;                     else if (pos >= buffer.length)           //如果>0 说明有数据需要重读            if (markpos > 0) {                //保留字节个数                int sz = pos - markpos;                //读取至缓冲区头部                System.arraycopy(buffer, markpos, buffer, 0, sz);                //重置pos 及markpos                 pos = sz;                markpos = 0;            } else if (buffer.length >= marklimit) {                markpos = -1;                    pos = 0;                   } else if (buffer.length >= MAX_BUFFER_SIZE) {                throw new OutOfMemoryError("Required array size too large");            } else {                        //通过 marklimit 需要扩容 一般为pos*2  这是pos为原缓冲区的大小                int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?                        pos * 2 : MAX_BUFFER_SIZE;                if (nsz > marklimit)                    nsz = marklimit;                    //创建一个新的缓冲区                byte nbuf[] = new byte[nsz];                //初始化nbuf                System.arraycopy(buffer, 0, nbuf, 0, pos);                if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {                    throw new IOException("Stream closed");                }                buffer = nbuf;            }        count = pos;        //从in中读取数据至缓冲区         int n = getInIfOpen().read(buffer, pos, buffer.length - pos);        if (n > 0)            count = n + pos;    }

BufferedInputStream 主要的基本都介绍了,当然 还有mark,reset等方法,其实就是用来标记和恢复用途,不多分析了。

阅读全文
0 0