FileOutputStream与ByteArrayOutputStream的区别

9
我正在阅读别人的代码。以下是它的主要内容。
一个类使用GZIPInputStream和GZIPOutputStream来压缩和解压缩文件。
下面是压缩过程中的一部分代码。 inputfile和outputFile是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
@sblundy,它们来自像commons-io这样的库。 - Russell
4个回答

11

哎呀,听起来他们是从不同的源代码中复制并粘贴过来的? :-P 不,说真的,除非你需要检查解压缩后的数据,否则你可以只使用一个BufferedOutputStream进行压缩和解压缩。


1
在这种情况下,您会建议我使用new BufferedOutputStream(new FileOutputStream(outputFile)而不是new FileOutputStream(outputFile)吗?这样会有性能提升吗? - Russell
1
我认为,这可能会提高性能,但真正的解决方案是使用BufferedInputStream和BufferedOutputStream。 - Peter Lawrey
2
没错,使用BufferedInput和BufferedOutput是高效的方法。 - A_Var
@Russell:确实,是的,请在两个地方都使用缓冲流。(虽然其他两个人已经回答了你的问题,但我还是想给你一个完整的答案。:-)) - C. K. Young
请考虑将输入流也包装在BufferedInputStream中,无论是压缩还是解压缩都要这样做。 - C. K. Young

6

ByteArrayOutputStream更加占用内存,因为它将整个内容存储在Java的内存中(以byte[]的形式)。FileOutputStream直接写入磁盘,因此更少占用内存。在这种特定情况下,我没有看到使用ByteArrayOutputStream的任何合理理由。它不会修改单个字节。它只是在之后无需更改地写入文件。因此,这是一个不必要的中间步骤。


3
程序员在压缩时使用了FileInputStream,在解压时使用了buffer。我认为原因是,如果在读取文件期间出现错误,什么都不会发生,只会失败并抛出异常。
如果在解压缩过程中出现失败,并且您已经开始向文件写入内容,则文件会损坏。所以他决定先写入缓存,然后当解压完成时再将缓存写入磁盘。这个解决方案对于处理相对较小的文件来说是可以的。否则,这将需要太多内存,可能会产生OutOfMemeoryError。
我会直接将zip文件提取到临时文件中,然后将临时文件重命名为永久名称。最后的代码块应该负责删除临时文件。

好的想法。在代码中似乎没有地方处理写入失败的情况,所以我猜在这种特殊情况下,只能进行复制粘贴或在不同的时间编写。 - Russell

2

ByteArrayOutputStream 会给他/她一个漂亮的 OutOfMemoryError 吗?

说真的,它们可能是在不同的时间完成的。如果可以的话,我建议查看版本控制系统的日志。


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