Java IO-BufferedInputStream

本文深入解析了BufferedInputStream的工作原理,包括其默认缓冲区大小、最大缓冲区限制、内部缓冲数组,以及初始化和读取数据的方法。此外还简要提到了mark和reset方法的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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等方法,其实就是用来标记和恢复用途,不多分析了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值