性能:BufferedOutputStream与FileWriter

9
我一直使用FileWriter在Java中将文本写入文件。显然,也可以使用BufferedOutputStream。仔细阅读两个Javadoc之后,我似乎无法确定哪种方法更快/更有效。
因此我想问:这两种文件I/O方法之间是否存在性能差异(即使很小)?如果有,它们是什么,为什么?如果没有,为什么它们实际上是相同的?
是否有某些场景中一个比另一个更好用呢?谢谢提前!
2个回答

10

如果你想比较使用FileWriterBufferedOutputStream写文本文件的速度,后者应该更快,因为它需要较少的I/O操作。

  • 在使用FileWriter时,每次调用写入方法都会立即持久化(不带缓冲)。
  • 在使用BufferedOutputStream时,只有当缓冲区满了(或通过flush方法显式刷新缓冲区)时,数据才会被写入磁盘。

但是,如果你要写文本文件,则应该使用Writer;在这种情况下,我们可以将FileWriterBufferedWriter进行比较:

观察

FileWriter fw = new FileWriter(...)

BufferedWriter bw = new BufferedWriter(new FileWriter(...)

你在I/O操作的数量方面处于相同的情况。


FileWriter 内部使用 FileOutputStream。使用 FileWriter 的原因是,当您写入文件时(例如将 Java 内部字符串编码为 UTF-8),它会自动使用默认字符编码。如果您使用 OutputStream,则需要在每次写入时手动进行编码:

因此,以下是使用 BufferedWriter 的示例:

bw.write("Hello");

对应于BufferedOutputStream的示例:

bos.write("Hello".getBytes(Charset.forName("utf-8")));

如果您的默认编码是utf-8

OutputStream处理(原始)字节,而Writer处理(文本)字符。


3
一个 FileWriter文本 写入 文件,而一个 BufferedOutputStream 在将数据写入另一个二进制流之前在内存中保存任意二进制数据的缓冲区。它们完全不做同样的事情,因此比较它们的性能是没有意义的。
通常,缓冲可以提高应用程序的吞吐量,但会增加延迟。在文件的情况下,您可以每秒产生更多的输出,因为您可以一次传输更大的块到磁盘上,所以每个字节的开销更低。另一方面,在内存中缓冲数据时,它并没有被写入磁盘,因此对于任何特定的字节,需要更长的时间才能写入磁盘。
FileWriter 的情况下,它已经具有帮助将字符编码为字节的内部缓冲区。添加更多的缓冲区可能没有太大的价值。

谢谢@Joni (+1) - 有趣的观察,但是你能不能使用BufferedOutputStream将文本写入文件?!?这篇文章似乎认为可以。如果那篇文章是正确的,那么尽管FileWriterBufferedOutputStream可能用于2个不同的用途,但在写入文本到文件时比较它们的性能是可能的(也就是我的问题所在)。 - user1768830
@Joni,非常有趣的东西!根据这个SO问题,似乎可以覆盖FileWriter使用的内部缓冲区。我想尝试一下,即使只是为了自己的娱乐。但我无论如何都想不出如何配置OutputStreamWriterFileOutputStream并将它们注入到FileWriter构造函数中 - 你有什么想法吗?我在哪里指定新的缓冲区大小?再次感谢您迄今为止提供的所有帮助! - user1768830
正如您在文章中所看到的,为了使用BufferedOutputStream编写文本,首先必须手动将任何文本转换为字节,通过调用getBytes,这很不方便并且会创建一个立即变成垃圾的字节数组。 - Joni
FileWriter 实际上是 OutputStreamWriter 的子类,它被设置成只能写入 FileOutputStream,所以如果你想自定义一些属性,你可以创建一个连接到 FileOutputStreamOutputStreamWriter。但是无法更改内部缓冲区大小。默认的 8k 缓冲区对于大多数应用程序来说已经足够大了。 - Joni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接