原文地址:
原来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个字符。
分享到:
相关推荐
缓冲流如`BufferedReader`和`BufferedWriter`提高了读写效率,它们会在内部创建一个缓冲区,减少实际的物理I/O操作次数。 6. **字符编码与转换** Java的字符流默认使用UTF-8编码,但可以使用`InputStreamReader`...
首先要明白不带缓冲的概念:所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用,不是函数库的调用。系统内核对磁盘的读写都会提供一个块缓冲(在有些地方也被称为内核高速缓存),当用write函数对其写...
首先,我们要明白,Java中的流分为字节流和字符流两大类。字节流处理的是8位的字节,而字符流处理的是16位的Unicode字符。字节流又分为输入流(InputStream)和输出流(OutputStream),字符流则有Reader和Writer。...
缓冲流(Buffered Stream)如BufferedReader和BufferedWriter,可以提高读写效率,通过一次性处理大量数据而不是每次处理一个字节或字符。 5. **对象序列化与反序列化** Java提供了Serializable接口,使得对象...
此外,BufferedReader和BufferedWriter等缓冲流类可以提高读写效率,它们会在内存中建立缓冲区,减少实际磁盘操作的次数。FilterInputStream和FilterOutputStream等过滤流则提供了一种装饰者模式,方便添加额外的...
### 教你彻底明白Java的IO系统 #### 一、Java IO系统概述 Java的输入/输出(Input/Output,简称IO)系统是Java编程语言中处理数据输入和输出的核心部分。它支持多种数据流(stream)的创建与管理,包括以字节为...
- `BufferedInputStream`:为字节流提供缓冲机制,提高读取效率。 - `LineNumberInputStream`:记录输入流中行号的位置。 - `PushbackInputStream`:允许将一个字节压回输入流。 - **字符流过滤器**: - `...
在 Java 中,IO 是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。Java 中的 IO 系统可以分为两种类型:以字节为导向的流和以 Unicode 字符为导向的流。 以字节为导向的流 以字节为...
除了基本的输入输出流外,Java还提供了`FilterInputStream`和`FilterOutputStream`,它们充当装饰器,允许在现有流的基础上添加额外功能,如缓冲、数据格式化等。例如,`DataInputStream`为`InputStream`添加了读取...
首先,我们要明白IO的基本原理。输入(Input)是获取数据的过程,例如键盘打字、鼠标点击或从文件读取数据;而输出(Output)则是将数据展示或保存到外部设备,如屏幕显示、打印机打印或写入文件。在Java中,IO操作...
一直不明白未什么,解释请看下。 输入缓冲是行缓冲。当从键盘上输入一串字符并按回车后,这些字符会首先被送到输入缓冲区中存储。每当按下回车键后,cin.get() 就会检测输入缓冲区中是否有了可读的数据。cin.get()...
在无线通信领域,多媒体流的传输是至关重要的技术环节,特别是在现代移动设备中,如智能手机、平板电脑等无线通信终端。这些设备不仅需要接收和发送文本、图片,更需要高效地处理音频、视频等多媒体数据流。本话题将...
7. **IO流**:字节流、字符流、缓冲流、对象流、转换流、管道流、输入输出流的关闭、NIO(New IO)。 8. **网络编程**:套接字(Socket)、服务器套接字(ServerSocket)、URL、URLConnection。 9. **反射**:...
流是数据传输的抽象表示,可以是字符流(处理字符数据)或字节流(处理二进制数据)。 - **节点流(Node Stream)**:直接连接到数据源或目的地的流,如FileInputStream和FileOutputStream。 - **处理流(Filter ...
提示 学习Flume必须明白这几个概念,Event英文直译是事件,但是在Flume里表示数据传输的一个最小单位(被Flume收集的一条条日志又或者一个个的二进制文件,不管你在外面叫什么,进入Flume之后它就叫event)。...