码迷,mamicode.com
首页 > 其他好文 > 详细

BufferedInputStream源码常用部分分析

时间:2016-03-28 02:17:54      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:

    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];
    }

构造函数,无参和有参

无参的其实是设置默认缓冲大小,有参则可以修改,buf则是缓冲数组

    private static int DEFAULT_BUFFER_SIZE = 8192;
    protected volatile byte buf[];

再看看read()方法

    public synchronized int read() throws IOException {
        if (pos >= count) {
            fill();
            if (pos >= count)
                return -1;
        }
        return getBufIfOpen()[pos++] & 0xff;
    }
    protected int count;
    protected int pos;
    private void fill() throws IOException {
        byte[] buffer = getBufIfOpen();
        if (markpos < 0)
            pos = 0;            /* no mark: throw away the buffer */
        else if (pos >= buffer.length)  /* no room left in buffer */
            if (markpos > 0) {  /* can throw away early part of the buffer */
                int sz = pos - markpos;
                System.arraycopy(buffer, markpos, buffer, 0, sz);
                pos = sz;
                markpos = 0;
            } else if (buffer.length >= marklimit) {
                markpos = -1;   /* buffer got too big, invalidate mark */
                pos = 0;        /* drop buffer contents */
            } else if (buffer.length >= MAX_BUFFER_SIZE) {
                throw new OutOfMemoryError("Required array size too large");
            } else {            /* grow buffer */
                int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?
                        pos * 2 : MAX_BUFFER_SIZE;
                if (nsz > marklimit)
                    nsz = marklimit;
                byte nbuf[] = new byte[nsz];
                System.arraycopy(buffer, 0, nbuf, 0, pos);
                if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {
                    // Can‘t replace buf if there was an async close.
                    // Note: This would need to be changed if fill()
                    // is ever made accessible to multiple threads.
                    // But for now, the only way CAS can fail is via close.
                    // assert buf == null;
                    throw new IOException("Stream closed");
                }
                buffer = nbuf;
            }
        count = pos;
        int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
        if (n > 0)
            count = n + pos;
    }
    private byte[] getBufIfOpen() throws IOException {
        byte[] buffer = buf;
        if (buffer == null)
            throw new IOException("Stream closed");
        return buffer;
    }

getBufIfOpen()方法buf数组不为空则获取当前buf数组(close方法设空)

    protected int markpos = -1;
    protected int marklimit;
    private InputStream getInIfOpen() throws IOException {
        InputStream input = in;
        if (input == null)
            throw new IOException("Stream closed");
        return input;
    }

相似的getInIfOpen()方法如果in不为空则获取当前in(close方法设空)

没有mark的时候,fill()就是从InputStream中尝试读一个缓冲数组长度到buffer中,count为实际读取长度

说实话这里我想了好久,数组也是对象,除了boolean, byte, short, char, int, long, float, double之外都是对象,new int[5] instanceof Object在IDE中打印出来也确实是true。更改buffer实际就是对buf的操作。

read()读取buf中索引为pos的值并和0xff按位与(为了将-128~-1转为128~255得到0~255),并且pos加1。

看出pos表示buffer中读到的位置,加1后供下次read,超过count的实际读取长度时再次调用fill(),重新读流后pos为0,如果流读完了count为-1,于是return -1

mark我还没用过- -用到了再往下写

BufferedInputStream源码常用部分分析

标签:

原文地址:http://www.cnblogs.com/wqbill/p/5326749.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!