61

在 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 中看不到任何说明这些方法之一是否必要或首选的内容。有什么建议吗?似乎首先压缩输出然后缓冲它以进行写入会更有效。

4

2 回答 2

97

你应该总是用 包裹,BufferedOutputStreamZipOutputStream不是反过来。请参阅以下代码:

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()andcloseEntry()方法在BufferedOutputStream. 不调用这些方法ZipOutputStream会引发异常java.util.zip.ZipException: no current ZIP entry

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

编辑

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

于 2013-06-19T11:38:05.987 回答
22

你应该:

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

因为您想缓冲写入磁盘的内容(因为这在大数据块中比在许多小数据块中更有效)。


new BufferedOutputStream(new ZipOutputStream(dest));

会在 zip 压缩之前缓冲。但这一切都发生在内存中,不需要缓冲,因为很多小内存访问的速度与一些大内存访问的速度差不多。在内存中,所需的时间通常与读/写的字节数成正比。

如评论中所述:

ZipOutputStream不属于其中的方法BufferedOutputStream也将不可用。例如putNextEntrycloseEntry

于 2013-01-22T15:45:04.863 回答