使用Java ZipOutputStream和BufferedOutputStream的首选方法

时间:2013-01-22 15:43:02

标签: java io outputstream

在Java中,首先实例化ZipOutputStream还是先BufferedOutputStream是否重要?例如:

FileOutputStream dest = new FileOutputStream(file);
ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(dest));

// use zip output stream to write to

或者:

FileOutputStream dest = new FileOutputStream(file);
BufferedOutputStream out = new BufferedOutputStream(new ZipOutputStream(dest));

// use buffered stream to write to

在我的非科学时间里,我似乎无法在这里说出很多不同之处。我在Java API中看不到任何表明这些方法之一是必要的还是首选的。有什么建议?似乎首先压缩输出然后缓冲它以进行写入会更有效。

2 个答案:

答案 0 :(得分:74)

你应该始终用BufferedOutputStream包裹ZipOutputStream,而不是相反。请参阅以下代码:

FileOutputStream fos = new FileOutputStream("hello-world.zip");
BufferedOutputStream bos = new BufferedOutputStream(fos);
ZipOutputStream zos = new ZipOutputStream(bos);

try {
    for (int i = 0; i < 10; i++) {
        // not available on BufferedOutputStream
        zos.putNextEntry(new ZipEntry("hello-world." + i + ".txt"));
        zos.write("Hello World!".getBytes());
        // not available on BufferedOutputStream
        zos.closeEntry();
    }
}
finally {
    zos.close();
}

正如评论所说,putNextEntry()上没有closeEntry()BufferedOutputStream方法。如果不调用这些方法,ZipOutputStream会抛出异常java.util.zip.ZipException: no current ZIP entry

为了完整起见,值得注意的是finally子句只调用close()上的ZipOutputStream。这是因为按照惯例,所有内置Java输出流包装器实现都会传播关闭。

修改

我只是反过来测试了它。事实证明,用ZipOutputStream包裹BufferedOutputStream然后只在其上调用write()(不创建/关闭条目)将不会抛出ZipException。相反,生成的ZIP文件将损坏,其中没有任何条目。

答案 1 :(得分:20)

你应该:

ZipOutputStream out =  new ZipOutputStream(new BufferedOutputStream(dest));

因为你想缓冲写入光盘(因为这在大数据块中比在许多小数据块中更有效)。


new BufferedOutputStream(new ZipOutputStream(dest));
压缩之前

会缓冲。但这一切都发生在内存中并且不需要缓冲,因为很多小内存访问速度与几个大内存访问速度大致相同。 在内存中,所需的时间与读/写的字节数成正比。

如评论中所述:

不属于ZipOutputStream的{​​{1}}方法也不可用。例如。 BufferedOutputStreamputNextEntry