Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
到目前为止,我们看到的大多数示例都使用 unbuffered (无缓冲) I/O。这意味着每个读取或写入请求都由底层操作系统直接处理。这可以使程序效率低得多,因为每个这样的请求经常触发磁盘访问,网络活动或一些相对昂贵的其他操作。
为了减少这种开销,Java 平台实现了 buffered (缓冲) I/O 流。缓冲输入流从称为 buffer 的存储区读取数据;仅当缓冲区为空时才调用原生输入 API。类似地,缓冲输出流将数据写入缓冲区,并且仅在缓冲区已满时才调用原生输出 API。
程序可以使用我们现在多次使用的包装习惯用法将无缓冲的流转换为缓冲流,其中无缓冲的流对象被传递给缓冲流类的构造函数。以下是如何修改 CopyCharacters
示例中的构造函数调用以使用缓冲 I/O:
inputStream = new BufferedReader(new FileReader("xanadu.txt")); outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));
有四个用于包装无缓冲流的缓冲流类:BufferedInputStream
和 BufferedOutputStream
创建缓冲字节流,而 BufferedReader
和 BufferedWriter
创建缓冲字符流。
在关键点写出缓冲区通常是有意义的,而无需等待它填充。这被称为 flushing (刷新) 缓冲区。
一些缓冲的输出类支持 autoflush (自动刷新),由可选的构造函数参数指定。启用自动刷新时,某些关键事件会导致刷新缓冲区。例如,自动刷新的 PrintWriter
对象在每次调用 println
或 format
时刷新缓冲区。有关这些方法的更多信息,请参见 Formatting。
要手动刷新流,请调用其 flush
方法。flush
方法在任何输出流上都有效,但除非流是缓冲流,否则无效。