【问题标题】:Performance: BufferedOutputStream vs FileWriter性能:BufferedOutputStream 与 FileWriter
【发布时间】:2013-07-05 22:07:53
【问题描述】:

我一直使用FileWriter 将文本写入Java 文件。显然你也可以使用BufferedOutputStream。在仔细阅读了两个 javadocs 之后,我似乎无法分辨哪个更快/更有效。

所以我问:这两种文件 I/O 方法之间是否存在性能差异(即使很小)?如果是这样,它们是什么,为什么?如果不是,为什么它们实际上是相同的?

是否存在一种优先于另一种的情况?提前致谢!

【问题讨论】:

    标签: java performance file-io filewriter disk-io


    【解决方案1】:

    如果你真的想比较 FileWriterBufferedOutputStream 来写入文本文件,后者应该更快,因为 I/O 操作更少。

    • FileWriter 的情况下,对 write 方法的每次调用都将立即保持(无缓冲)。
    • 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 处理(文本)字符。

    【讨论】:

      【解决方案2】:

      FileWritertext 写入 files,而 BufferedOutputStream 在将任意二进制数据写入您拥有的另一个二进制流之前在内存中保存一个缓冲区提供。他们根本不做同样的事情,所以比较他们的表现是没有意义的。

      一般来说,缓冲可以提高应用程序的吞吐量,但会增加延迟。对于文件,您可以每秒产生更多的输出,因为您可以一次将较大的块传输到磁盘,因此每字节的开销较低。另一方面,当数据在内存中缓冲时,它不会被写入磁盘,因此任何特定字节都需要更长的时间才能写入磁盘。

      对于FileWriter,它已经有一个内部缓冲区,可以帮助将字符编码为字节。添加更多缓冲可能没有什么价值。

      【讨论】:

      • 感谢@Joni (+1) - 有趣的观察,但你能BufferedOutputStream向文件写入文本吗?!? This article 似乎不这么认为。如果那篇文章属实,那么虽然 FileWriterBufferedOutputStream 可能用于 2 种不同的用途,但在将文本写入到一个文件。
      • 再次,非常有趣的东西@Joni!根据this SO question 的说法,似乎可以覆盖FileWriter 使用的内部缓冲区。我想试试这个,如果没有别的,为了我自己的个人娱乐。对于我的生活,我无法弄清楚如何配置 OutputStreamWriterFileOutputStream 并将它们注入 FileWriter 构造函数 - 有什么想法吗?我将在哪里指定新的缓冲区大小?再次感谢迄今为止所有的大力帮助!
      • 正如您在文章中看到的那样,为了使用BufferedOutputStream 编写文本,他们首先通过调用getBytes 手动将任何文本转换为字节,这很不方便,并且会创建一个数组立即变成垃圾的字节
      • FileWriter 实际上是OutputStreamWriter rigged 的​​子类,所以它只能写入FileOutputStream,所以如果你想自定义一些属性,你可以创建一个OutputStreamWriter 连接到一个FileOutputStream。但是没有办法改变内部缓冲区的大小。对于大多数应用程序来说,8k 的默认缓冲区可能已经足够大了。
      猜你喜欢
      • 2018-02-12
      • 2017-09-17
      • 1970-01-01
      • 1970-01-01
      • 2013-07-27
      • 2011-08-11
      • 2017-12-02
      • 2017-06-17
      • 1970-01-01
      相关资源
      最近更新 更多