代码之家  ›  专栏  ›  技术社区  ›  Telcontar

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

  •  6
  • Telcontar  · 技术社区  · 16 年前

    我使用此代码创建一个.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”所有数据之前写入了一些内容,那么结果文件的字节大小可能与我选择其他缓冲区大小不同。

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

    读取数据-->处理数据-->创建.zip

    读取数据块-->处理数据块-->在.zip中写入数据块-->。| ^————————————————————————————————————————————————————————————————————————————————————————————————————————————————————---

    如果是这样的话,什么缓冲区大小是最好的?

    更新:

    我已经测试了这段代码,将缓冲区大小从1024更改为64,并压缩了相同的文件:对于1024字节,80kb结果文件比64字节缓冲区小3字节。哪个缓冲区大小最适合在最长的时间内生成最小的.zip?

    2 回复  |  直到 14 年前
        1
  •  10
  •   Dan Cristoloveanu    16 年前

    简短的回答:我会选像16K的。


    长回答:

    zip正在使用放气算法进行压缩( http://en.wikipedia.org/wiki/DEFLATE )。deflate是ziv lempel welch(在维基百科中搜索lzw)的一种味道。deflate使用LZ77和Huffman编码。

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

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

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

    当从1字节增加到1024字节时,您会丢失1023字节(理论上),并且在.read和.write方法中会减少大约1024个开销时间。 但是,当从1K增加到64K时,您将花费63K,这将使开销减少64倍。

    所以这伴随着收益递减,所以我会选择中间的某个地方(比如16K),并坚持下去。

        2
  •  0
  •   community wiki 2 revs ddimitrov    16 年前

    取决于您拥有的硬件(磁盘速度和文件搜索时间)。我想说,如果你不想压缩最后一滴性能,可以选择4K到64K之间的任何大小。因为它是一个短期存在的对象,无论如何它都会很快被收集起来。