`
ayis
  • 浏览: 187184 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

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

    博客分类:
  • java
阅读更多
原文地址:原来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个字符。

分享到:
评论

相关推荐

    彻底明白java中的IO流

    缓冲流如`BufferedReader`和`BufferedWriter`提高了读写效率,它们会在内部创建一个缓冲区,减少实际的物理I/O操作次数。 6. **字符编码与转换** Java的字符流默认使用UTF-8编码,但可以使用`InputStreamReader`...

    浅谈带缓冲I/O 和不带缓冲I/O的区别与联系

    首先要明白不带缓冲的概念:所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用,不是函数库的调用。系统内核对磁盘的读写都会提供一个块缓冲(在有些地方也被称为内核高速缓存),当用write函数对其写...

    个人资料Java io流

    首先,我们要明白,Java中的流分为字节流和字符流两大类。字节流处理的是8位的字节,而字符流处理的是16位的Unicode字符。字节流又分为输入流(InputStream)和输出流(OutputStream),字符流则有Reader和Writer。...

    彻底明白java的io系统

    缓冲流(Buffered Stream)如BufferedReader和BufferedWriter,可以提高读写效率,通过一次性处理大量数据而不是每次处理一个字节或字符。 5. **对象序列化与反序列化** Java提供了Serializable接口,使得对象...

    彻底明白Java的IO系统

    此外,BufferedReader和BufferedWriter等缓冲流类可以提高读写效率,它们会在内存中建立缓冲区,减少实际磁盘操作的次数。FilterInputStream和FilterOutputStream等过滤流则提供了一种装饰者模式,方便添加额外的...

    教你彻底明白Java的IO系统

    ### 教你彻底明白Java的IO系统 #### 一、Java IO系统概述 Java的输入/输出(Input/Output,简称IO)系统是Java编程语言中处理数据输入和输出的核心部分。它支持多种数据流(stream)的创建与管理,包括以字节为...

    Java,彻底明白Java语言中的IO系统

    - `BufferedInputStream`:为字节流提供缓冲机制,提高读取效率。 - `LineNumberInputStream`:记录输入流中行号的位置。 - `PushbackInputStream`:允许将一个字节压回输入流。 - **字符流过滤器**: - `...

    彻底明白 Java 语言中的IO系统

    在 Java 中,IO 是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。Java 中的 IO 系统可以分为两种类型:以字节为导向的流和以 Unicode 字符为导向的流。 以字节为导向的流 以字节为...

    彻底明白 Java 语言中的IO系统 .pdf

    除了基本的输入输出流外,Java还提供了`FilterInputStream`和`FilterOutputStream`,它们充当装饰器,允许在现有流的基础上添加额外功能,如缓冲、数据格式化等。例如,`DataInputStream`为`InputStream`添加了读取...

    IO/输入输出

    首先,我们要明白IO的基本原理。输入(Input)是获取数据的过程,例如键盘打字、鼠标点击或从文件读取数据;而输出(Output)则是将数据展示或保存到外部设备,如屏幕显示、打印机打印或写入文件。在Java中,IO操作...

    浅谈c++中的while(cin)问题

    一直不明白未什么,解释请看下。 输入缓冲是行缓冲。当从键盘上输入一串字符并按回车后,这些字符会首先被送到输入缓冲区中存储。每当按下回车键后,cin.get() 就会检测输入缓冲区中是否有了可读的数据。cin.get()...

    行业分类-设备装置-无线通信终端中多媒体流的传输装置和方法.zip

    在无线通信领域,多媒体流的传输是至关重要的技术环节,特别是在现代移动设备中,如智能手机、平板电脑等无线通信终端。这些设备不仅需要接收和发送文本、图片,更需要高效地处理音频、视频等多媒体数据流。本话题将...

    没整明白这些问题 别说你学过JAVA(pdf格式)

    7. **IO流**:字节流、字符流、缓冲流、对象流、转换流、管道流、输入输出流的关闭、NIO(New IO)。 8. **网络编程**:套接字(Socket)、服务器套接字(ServerSocket)、URL、URLConnection。 9. **反射**:...

    学习资料

    流是数据传输的抽象表示,可以是字符流(处理字符数据)或字节流(处理二进制数据)。 - **节点流(Node Stream)**:直接连接到数据源或目的地的流,如FileInputStream和FileOutputStream。 - **处理流(Filter ...

    数据采集之Flume.xmind

    提示 学习Flume必须明白这几个概念,Event英文直译是事件,但是在Flume里表示数据传输的一个最小单位(被Flume收集的一条条日志又或者一个个的二进制文件,不管你在外面叫什么,进入Flume之后它就叫event)。...

Global site tag (gtag.js) - Google Analytics