JAVA 篇之IO BufferInputStream,BufferOutPutStream

这两个流是带有缓存功能的流(一般读取文件都建议用这两个)

1、BufferInputStream介绍

主要介绍fill()方法(这个方法体现和不带缓存区方法的不同之处)

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); //重要,把操作系统内核数据拷贝到JVM空间,这个是
            //一个块的拷贝啊(不在是单字节的读取方法了,当然最后从buffer读取是单字节读取形式,但是和磁盘IO交换
            的次数变少了,大大的提示了性能)!!!
            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;
}

这里设计到几个变量  markpos,pos,marklimit(看过JAVA NIO的很快就知道其他的意思)

markpos 是读取的开始位置,读取是 markpos - pos , marklimit最大的标记限制,不能超过pos的位置

 

2、BufferOutputStream

对于缓存输出流,其实也是一样,把JVM的buffer数据输出到操作系统内核空间(也是块传输)

private void ensureCapacity(int newcount) {
    if(newcount > this.buf.length) {
        byte[] newbuf = new byte[Math.max(this.buf.length << 1, newcount)];
        System.arraycopy(this.buf, 0, newbuf, 0, this.count); //最后也是调用本地方法copy数据
        this.buf = newbuf;
    }

}

上面的方法是在ByteArrayBuffer里面

 

给出一段列子

try( BufferedInputStream bfi = new BufferedInputStream(new FileInputStream(new File("src")));
     BufferedOutputStream bfo = new BufferedOutputStream(new FileOutputStream(new File("dec")))){
    int length = 0;
    for(;;){
       if( (length = bfi.read()) !=-1){
           bfo.write(length);
       }else
           break;
    }
}catch (Exception e){
    e.printStackTrace();
}

 

 

 

 

 

转载于:https://my.oschina.net/chenping12/blog/1479744

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值