这些Java教程是为JDK 8编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
有关Java SE 9及以后版本中更新的语言特性的摘要,请参阅Java语言变化。
有关所有JDK版本的新功能、增强功能和已删除或已弃用选项的信息,请参阅JDK发行说明。
到目前为止,我们看到的大多数示例都使用了非缓冲的输入/输出(I/O)。这意味着每个读取或写入请求都直接由底层操作系统处理。这可能会使程序效率降低,因为每个此类请求通常会触发磁盘访问、网络活动或其他相对昂贵的操作。
为了减少这种开销,Java平台实现了缓冲输入/输出流。缓冲输入流从称为缓冲区的内存区域中读取数据;只有在缓冲区为空时才调用本机输入API。类似地,缓冲输出流将数据写入缓冲区,只有在缓冲区满时才调用本机输出API。
程序可以使用我们已经多次使用过的封装方法将非缓冲流转换为缓冲流,其中非缓冲流对象传递给缓冲流类的构造函数。以下是如何修改CopyCharacters
示例中的构造函数调用以使用缓冲I/O的方式:
inputStream = new BufferedReader(new FileReader("xanadu.txt")); outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));
有四个缓冲流类用于封装非缓冲流:BufferedInputStream
和BufferedOutputStream
创建缓冲字节流,而BufferedReader
和BufferedWriter
创建缓冲字符流。
在关键点写出缓冲区内容而不等待缓冲区填满通常是有意义的。这被称为刷新缓冲区。
一些缓冲输出类支持自动刷新,由可选的构造函数参数指定。当启用自动刷新时,某些关键事件会导致缓冲区被刷新。例如,一个启用了自动刷新的PrintWriter
对象在每次调用println
或format
时都会刷新缓冲区。有关这些方法的更多信息,请参阅格式化。
要手动刷新流,请调用其flush
方法。flush
方法在任何输出流上都有效,但仅当流具有缓冲时才会产生效果。