原文地址:
原来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个字符。
分享到:
相关推荐
首先要明白不带缓冲的概念:所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用,不是函数库的调用。系统内核对磁盘的读写都会提供一个块缓冲(在有些地方也被称为内核高速缓存),当用write函数对其写...
一直不明白未什么,解释请看下。 输入缓冲是行缓冲。当从键盘上输入一串字符并按回车后,这些字符会首先被送到输入缓冲区中存储。每当按下回车键后,cin.get() 就会检测输入缓冲区中是否有了可读的数据。cin.get()...
提示 学习Flume必须明白这几个概念,Event英文直译是事件,但是在Flume里表示数据传输的一个最小单位(被Flume收集的一条条日志又或者一个个的二进制文件,不管你在外面叫什么,进入Flume之后它就叫event)。...
现在继续文件输入, 需要一点技巧, 所以先确认你已经明白了流操作,对 "和">>" 比较熟悉了, 因为你接下来还要用到他们。继续… 二、ASCII 输入 输入和"cin" 流很像. 和刚刚讨论的输出流很像, 但你要考虑几件...
7)VBV缓冲区大小:缓冲区大的话,编码优化会好一些,但是解码的时候也要求大一些的缓冲区。因此,vcd/svcd标准中参数是固定的,否则可能机器无法播放。 8)Pofile & level(类别与级别): 这个参数是mpeg1没有的。...
TiXmlPrinter:输出到一个std::string或者内存缓冲区中。 API还不是很简练。 将来会增加打印选项。 在将来的版本中可能有些细微的变化,因为它会被改进和扩展。 流 设置了TIXML_USE_STL,TinyXML就能支持C++流...
Java服务器端开发面试题 Java服务器端开发面试题篇1 Hashcode()和equals(), 明白背后的原理,包括hashcode()的用法,各自的区别,如何,何时覆盖,为何覆盖 区别new String()和 申明的字符串的区别,String不变量,堆...
o 2.2 64 位机上的 64 位类型是什么样的? o 2.3 怎样定义和声明全局变量和函数最好? o 2.4 extern 在函数声明中是什么意思? o 2.5 关键字 auto 到底有什么用途? o 2.6 我似乎不能成功定义一个链表。我试过 ...
2.2 为什么struct x f . . . g; x thestruct; 不对? . . . . . . . . . . . . . 7 2.3 一个结构可以包含指向自己的指针吗? . . . . . . . . . . . . . . . 7 2.4 在C 语言中实现抽象数据类型什么方法最好? . . . ....
为什么必须管理内存 内存管理是计算机编程最为基本的领域之一。在很多脚本语言中,您不必担心内存是如何管理的,这并不能使得内存管理的重要性有一点点降低。对实际编程来说,理解您的内存管理器的能力与局限性至关...
在处理ADC高速率采集的大码流的时候,ADC的数字输出连接到一个来自IDT的高速FIFO存储器IDT7201(长达512字节),当存储器的缓冲区写满后,整个内存的内容被放到微控制器的内存,在那里对其中的样品进行进一步处理,...
在我写作《自己动手写操作系统》的时候,并没有想过今天会有一个第二版。原因在于,我希望这本书是用来填补空白的,而不是重复去做别人已经做得很好的事情。所谓填补空白,具体说就是让像我一样的操作系统爱好者在...
在我写作《自己动手写操作系统》的时候,并没有想过今天会有一个第二版。原因在于,我希望这本书是用来填补空白的,而不是重复去做别人已经做得很好的事情。所谓填补空白,具体说就是让像我一样的操作系统爱好者在...
- 其它功能都很容易理解, 你试一试就明白了 操作技巧 1、隐藏/显示窗口Ctrl+D 2、按住Ctrl键再点[刷新]可保持现有用户,搜索新上线的用户 3、打开发送/接收消息窗口Ctrl+Alt+S/R(需要进行详细设置) 4、...