IT-Swarm.Net

使用Java ZipOutputStream和BufferedOutputStream的首选方法

在Java中,我是否实例化一个 ZipOutputStream first,或 BufferedOutputStream first?例:

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

50
jjathman

你应该总是用BufferedOutputStreamname__包装ZipOutputStreamname__,而不是相反。请参阅以下代码:

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();
}

正如评论所说BufferedOutputStreamname__上没有putNextEntry()closeEntry()方法。不调用那些方法ZipOutputStreamname__会抛出异常Java.util.Zip.ZipException: no current Zip entry。.

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

编辑

我只是反过来测试它。事实证明,将ZipOutputStreamname__与BufferedOutputStreamname__包装在一起然后只调用write()(不创建/关闭条目)将不会抛出ZipExceptionname__。相反,生成的Zip文件将损坏,其中没有任何条目。.

74
Daniel Dinnyes

快速,可靠且价格合理的云托管

注册并在30天内获得$50奖金!

你应该:

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

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


这个

new BufferedOutputStream(new ZipOutputStream(dest));

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

如评论中所述:

不属于ZipOutputStreamBufferedOutputStream的方法也不可用。例如。 putNextEntrycloseEntry。.

20
MrSmith42