今天终于明白了什么是缓冲流

原文地址:原来BufferedReader不能和InputStream交替使用(转)

原文是这样的意思,用BufferedReader封装一个InputStream,再用DataInputStream封装这个InputStream,这样做之后,先用BufferedReader从流中读取一行,然后分别用这个InputStream读取一个字符和DataInputStream读取一行,再用BufferedReader读取一行,结果BufferedReader均能读到数据,而InputStream和DataInputStream均读不到数据.数据流中只有40多个字符。这说明了,BufferedReader第一次读取时,就把这40多个字符都读取出来,缓冲起来了,后面每次读的时候,都只是从缓冲里拿出来。40多个字符就一次被BufferedReader读进去缓存起来了,所以InputStream和DataInputStream就都读不到字符了。
原文并猜想,如果流中的数据够多到BufferedReader缓存不下来的时候,InputStream和DataInputStream就能读到数据了。

确实是这样的,在BufferedReader的源码中,有

private static int defaultCharBufferSize = 8192;

这个是默认缓冲区的大小,BufferedReader一次读取时,能缓存这么多个字符。

我对原文的程序修改了一下:

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class TestByteArray {

    public byte[] generateByte() {
        // 构造一个测试流,这样就不用从文件里面读取了,在这个流里面使用了大量的回车换行("\r\n"),这样方便过会的测试
        // 过会,我会通过把字符串转换成byte数组,然后通过ByteArrayInputStream来构造一个数据流
        String str = "a\r\nbc\r\ndef\r\nghi\r\nj\r\nklmn\r\nopqr\r\ns\r\ntuvwx";    // 这个字符串的长度是40个。    
        StringBuffer buffer = new StringBuffer();
        // 通过循环,返回足够大的字符数据
        for(int i=0 ; i < 205; i++){
            buffer.append(str);
        }
        str = buffer.toString();
        System.out.println(str.length());            // 打印字符串的长度
        return str.getBytes();
    }

    public static void main(String[] args) throws IOException {
        
        TestByteArray self = new TestByteArray();
        byte[] be = self.generateByte();
        InputStream in = new ByteArrayInputStream(be);
        BufferedReader bufferReader = new BufferedReader(new InputStreamReader(
                in));
        // 使用DataInputStream而不直接使用Inputstream是因为这样方便,因为他提供了读取行
        // 不过听说他读取行时把字节转变为字符时会有问题,所以不推荐使用,不过我们在这只做测试就没关系了
        DataInputStream dataInputStream = new DataInputStream(in);

        // 先读取流里面的一行数据
        System.out.println("bufferReader=" + bufferReader.readLine());
        // 回过头来使用dataInputStream读取数据,会发现什么也读取不到
        System.out.println("dataInputStream=" + dataInputStream.readLine());
        // 回过头来使用inputstream读取数据,会发现什么也读取不到
        System.out.println("in=" + in.read());
        // InputStream读取不到数据,然后再使用原来的BufferedReader来读取数据,发现是接着原来读取的.
        System.out.println("bufferReader=" + bufferReader.readLine());

        // 我们上面的字符串比较小,我想如果字符串,大到缓存装不下的时候,使用inputstream回头去读取数据,肯定是能读取到的
        // 这个我就不测试了

    }

}

在这个修改后的程序中,通过循环,返回足够大的字符串,8200个,超过了BufferedReader的默认缓存,结果InputStream和DataInputStream就都能读到字符了。运行这个程序结果如下:
8200
bufferReader=a
dataInputStream=s
in=116
bufferReader=bc

修改循环的次数为204,字符串的长度为8160,它小于8192,结果InputStream和DataInputStream就均读不到数据了。

这足以说明,BufferedReader是把数据缓存起来了,并且缓存的大小是8192个字符。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值