使用Java创建.zip存档的缓冲区大小是多少?

时间:2008-10-14 11:14:46

标签: java zip buffer

我使用此代码创建一个包含文件列表的.zip:

ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));

for (int i=0;i<srcFiles.length;i++){
    String fileName=srcFiles[i].getName();
    ZipEntry zipEntry = new ZipEntry(fileName);
    zos.putNextEntry(zipEntry);
    InputStream fis = new FileInputStream(srcFiles[i]);
    int read;
    for(byte[] buffer=new byte[1024];(read=fis.read(buffer))>0;){
        zos.write(buffer,0,read);
    }
    fis.close();
    zos.closeEntry();
}
zos.close();

我不知道zip算法和ZipOutputStream是如何工作的,如果在我读取并发送到'zos'所有数据之前它写了一些东西,结果文件的字节大小可能与我选择另一个缓冲区大小。

换句话说,我不知道算法是否像:

阅读数据 - &gt;处理数据 - &gt;创建.ZIP

阅读数据块 - &gt;处理数据块 - &gt; WRITE CHUNK IN .ZIP - &gt; | ^ ------------------------------------------------- -------------------------------------------------- --------------------------

如果是这种情况,哪种缓冲区大小最好?

更新

我测试了这段代码,将缓冲区大小从1024更改为64,并压缩相同的文件:使用1024字节时,80 KB结果文件比使用64字节缓冲区小3个字节。哪个是在最短的时间内产生最小.zip的最佳缓冲区大小?

2 个答案:

答案 0 :(得分:10)

简短回答:我会选择像16k这样的东西。


答案很长:

ZIP使用DEFLATE算法进行压缩(http://en.wikipedia.org/wiki/DEFLATE)。 Deflate是Ziv Lempel Welch(LZW的搜索维基百科)的味道。 DEFLATE使用LZ77和霍夫曼编码。

这是字典压缩,据我所知,从算法的角度来看,将数据输入到deflater时使用的缓冲区大小应该几乎没有影响。 LZ77的最大影响是字典大小和滑动窗口,它们不受示例中缓冲区大小的控制。

我认为你可以尝试不同的缓冲区大小,如果你想要并绘制图形,但我相信你不会看到压缩比有任何显着变化(3/80000 = 0.00375%)。

缓冲区大小对速度的影响最大的是由于在调用FileInputStream.read和zos.write时执行的开销代码量。从这个角度来看,你应该考虑你获得的和你花的钱。

当从1字节增加到1024字节时,你会丢失1023字节(理论上),并且.read和.write方法的开销时间减少了~1024。 然而,当从1k增加到64k时,你花费63k,这减少了64倍的开销。

所以这会带来收益递减,因此我会选择中间某处(比方说16k)并坚持下去。

答案 1 :(得分:0)

取决于您拥有的硬件(磁盘速度和文件搜索时间)。我想说如果你对挤压最后一滴性能不感兴趣,可以选择4k到64k之间的任何尺寸。由于它是一个短命的物体,它无论如何都会被快速收集。