java zipentry 压缩率_java – ZipEntry.STORED用于已经压缩的文件?

java zipentry 压缩率_java – ZipEntry.STORED用于已经压缩的文件?我正在使用ZipOutputStream压缩一堆文件,这些文件是已压缩格式的混合,以及许多大型高度可压缩格式,如纯文本.大多数已经压缩的格式都是大文件,因为它们永远不会变小,有时会在极少数情况下变得稍微大一些,因此在重新压缩它们时花费cpu和内存是没有意义的.当我检测到预压缩文件时,我试图使用.setMethod(ZipEntry.STORED),但它抱怨我需要提供这些文件的大小,compress…

java zipentry 压缩率_java – ZipEntry.STORED用于已经压缩的文件?

我正在使用ZipOutputStream压缩一堆文件,这些文件是已压缩格式的混合,以及许多大型高度可压缩格式,如纯文本.

大多数已经压缩的格式都是大文件,因为它们永远不会变小,有时会在极少数情况下变得稍微大一些,因此在重新压缩它们时花费cpu和内存是没有意义的.

当我检测到预压缩文件时,我试图使用.setMethod(ZipEntry.STORED),但它抱怨我需要提供这些文件的大小,compressedSize和crc.

我可以使用以下方法使其工作,但这需要我读取文件两次.一旦计算CRC32然后再次实际将文件复制到ZipOutputStream中.

// code that determines the value of method omitted for brevity

if (STORED == method)

{

fze.setMethod(STORED);

fze.setCompressedSize(fe.attributes.size());

final HashingInputStream his = new HashingInputStream(Hashing.crc32(), fis);

ByteStreams.copy(his,ByteStreams.nullOutputStream());

fze.setCrc(his.hash().padToLong());

}

else

{

fze.setMethod(DEFLATED);

}

zos.putNextEntry(fze);

ByteStreams.copy(new FileInputStream(fe.path.toFile()), zos);

zos.closeEntry();

有没有办法提供这些信息而无需两次读取输入流?

最佳答案 简答:

我无法确定一种只读取文件一次的方法,并根据我必须解决此问题的时间用标准库计算CRC.

我确实找到了一个优化,平均减少了约50%的时间.

我预先计算要与ExecutorCompletionService同时存储的文件的CRC,该ExecutorCompletionService仅限于Runtime.getRuntime().availableProcessors()并等待它们完成.其有效性取决于需要CRC计算的文件数.随着文件越多,效益越大.

然后在.postVisitDirectories()中,在PipedOutputStream中围绕PipedOutputStream包装一个PipedOutputStream来运行临时线程,将ZipOutputStream转换为InputStream我可以传入HttpRequest将ZipOutputStream的结果上传到远程服务器连续编写所有预先计算的ZipEntry / Path对象.

这对于处理300 GB的即时需求来说已经足够了,但是当我完成10TB工作时,我将着眼于解决它并尝试找到更多优势而不会增加太多复杂性.

如果我想出一些明智的时间,我会用新的实现来更新这个答案.

答案很长:

我最后写了一个洁净室ZipOutputStream,支持多部分zip文件,智能压缩级别与STORE,并且能够在我读取时计算CRC,然后在流的末尾写出元数据.

为什么ZipOutputStream.setLevel()交换不起作用:

The ZipOutputStream.setLevel(NO_COMPRESSION/DEFAULT_COMPRESSION)

hack is not a viable approach. I did extensive tests on hundreds of

gigs of data, thousands of folders and files and the measurements were

conclusive. It gains nothing over calculating the CRC for the

STORED files vs compressing them at NO_COMPRESSION. It is actually

slower by a large margin!

In my tests the files are on a network mounted drive so reading

the files already compressed files twice over the network to

calculate the CRC then again to add to the ZipOutputStream was as

fast or faster than just processing all the files once as DEFLATED

and changing the .setLevel() on the ZipOutputStream.

There is no local filesystem caching going on with the network access.

This is a worse case scenario, processing files on the local disk will

be much much faster because of local filesystem caching.

So this hack is a naive approach and is based on false assumptions. It is processing the

data through the compression algorithm even at NO_COMPRESSION level

and the overhead is higher than reading the files twice.

今天的文章java zipentry 压缩率_java – ZipEntry.STORED用于已经压缩的文件?分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/30042.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注