我的问题是zip压缩。我必须将文件分成几部分并平行压缩它们,然后以正确的顺序连接部件并将zip文件另存为一个文件。拆分文件和向主机发送部件不是问题 - 我正在使用jpvm。我的问题是:如何拆分压缩?我曾尝试使用java.util.zip.Deflater来压缩每个部分(结果是字节数组),然后将它们写入一个ZipOutputStream,但这似乎不起作用 - 保存到文件时压缩已经压缩的字节再一次。我是否必须使用deflater压缩每个部分,然后手动添加zip标题,一些校验和或类似的东西? Deflater会添加任何标题吗?我感谢任何帮助,谢谢!
答案 0 :(得分:4)
您需要使用nowrap
的{{1}}选项生成没有标题或预告片的原始deflate流。然后,您需要自己用适当的zip标题和预告片包装原始的deflate流。
要在多个处理器上创建单个deflate流,您需要能够使用{{3中的Deflater
操作将压缩输出刷新到字节边界(对于不是最后一块的片段) }}。 (最后一块将正常完成。)然后可以简单地连接各个部分。
Java 7(但不是Java 6)zlib通过Z_SYNC_FLUSH
方法的可选第四个参数支持此功能。可以将其设置为deflate()
。
以这种方式分解数据会降低压缩率,因为每个块都无法从前一个块的历史中受益。这可以使用SYNC_FLUSH
方法解决。向每个线程提供要压缩的数据以及在其之前的32K字节的未压缩数据。然后使用带有setDictionary()
的32K,然后使用setDictionary()
。
您可以直接使用zlib在C中看到documentation的并行压缩示例。
获得deflate流后,将其适当地换行以使其成为zip文件。请参阅pigz。您还需要计算未压缩数据的appnote for the zip file format才能填写这些字段。
答案 1 :(得分:0)
不幸的是你没有展示你的代码,所以我不能确定我完全理解你的代码。但是,据我了解您的问题,我可以向您推荐以下内容。
ZipOutputStream
将内容写入zip。创建带有后缀的文件,以便稍后加入内容。后缀应该是运行索引。由于您要将一个文件存储在多个zip文件中,因此每个zip使用一个条目。 ZipInputSteam
复制到FileOutputStream
。 不幸的是,我不明白你的多个主机意味着什么。你的意思是你的文件太大了,你可以同时在单独的机器上创建每个拉链?如果这是正确的,请修改#2,如下所示:读取文件片段时,将其内容发送到远程主机并在那里使用ZipOutputStream
。要从特定点读取文件,请使用InputStream.skip()
。