【问题标题】:FileOutputStream vs ByteArrayOutputStreamFileOutputStream 与 ByteArrayOutputStream
【发布时间】:2011-06-02 23:42:03
【问题描述】:

我正在阅读别人的代码。这是它的要点。

一个类使用 GZIPInputStream 和 GZIPOutputStream 压缩和解压缩文件。

这里是压缩过程中发生的事情的 sn-p。 inputFileoutputFile 是类 File 的实例。

FileInputStream fis = new FileInputStream(inputFile);
GZIPOutputStream gzos = new GZIPOutputStream(new FileOutputStream(outputFile));

//the following function copies an input stream to an output stream
IOUtils.copy(fis,gzos);

//outputFile is the compressed file
...

现在,这是解压过程中发生的事情。

GZIPInputStream gzis = new GZIPInputStream(new FileInputStream(inputFile));
ByteArrayOutputStream baos = new ByteArrayOutputStream();

//copies input stream to output stream
IOUtils.copy(gzis,baos);

//this method does as its name suggests
FileUtils.writeByteArrayToFile(outputFile, baos.toByteArray());

//outputFile is the decompressed file
...

原程序员在压缩时选择FileOutputStream,在解压时选择ByteArrayOutputStream的可能原因是什么?这让我很困惑。

除非有充分的理由,否则我认为我会将它们更改为一致以避免将来出现混淆。这是个好主意吗?

【问题讨论】:

  • IOUtils 和 FileUtils 是专有的还是来自 commons-io 之类的库?
  • @sblundy,它们来自 commons-io 之类的库。

标签: java file stream


【解决方案1】:

嘿,听起来他们从不同来源复制和粘贴代码? :-P 不,说真的,除非您需要检查解压缩的数据,否则您可以只使用BufferedOutputStream 进行压缩和解压缩。

【讨论】:

  • 在这种情况下,你会推荐我使用new BufferedOutputStream(new FileOutputStream(outputFile) 而不是new FileOutputStream(outputFile) 吗?会有性能提升吗?
  • 我会的,当真正的解决方案是使用 BufferedInputStream 和 BufferedOutputStream 时,这似乎可以提高性能。
  • 是的。 BufferedInput 和 BufferedOutput 是最有效的方法。
  • @Russell:确实,是的,在这两个地方都使用缓冲流。 (不是我需要说这个,因为其他两个已经这样做了,只是为了结束你的问题。:-))
  • P.S.考虑将输入流也包装在 BufferedInputStream 中,同样用于压缩和解压缩。
【解决方案2】:

ByteArrayOutputStream 会给他/她一个很好的OutOfMemoryError

说真的,它们可能是在不同的时间完成的。如果可以,我会查阅 VCS 日志。

【讨论】:

    【解决方案3】:

    ByteArrayOutputStream 更占用内存,因为它将整个内容存储在 Java 的内存中(类似于byte[])。 FileOutputStream 直接写入磁盘,因此占用的内存更少。在这种特殊情况下,我认为没有任何合理的理由使用ByteArrayOutputStream。之后它不会修改单个字节。之后它只是被原封不动地写入文件。因此,这是一个不必要的中间步骤。

    【讨论】:

      【解决方案4】:

      程序员在压缩时使用了FileInputStream,在解压时使用了缓冲区。我认为原因是,如果您在 duinr 读取文件时失败,则不会发生任何不好的事情。您只是失败并引发了异常。

      如果您在解压缩时失败并且您已经开始写入文件,则该文件已损坏。所以他决定先写缓冲区,等解压完成后再把缓冲区写到磁盘上。如果您正在处理相对较小的文件,则此解决方案是可以的。否则这需要大量内存并可能产生 OutOfMemeoryError。

      我会直接将 zip 解压缩到 temporary 文件,然后将临时文件重命名为其永久名称。 finally 块应该注意删除临时文件。

      【讨论】:

      • 好主意。代码中似乎没有地方可以处理失败的写入,所以我猜在这种特殊情况下,它是复制粘贴或在不同时间写入。
      猜你喜欢
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-26
      • 2017-09-17
      • 2017-06-17
      • 2015-10-15
      相关资源
      最近更新 更多