TL;DR:您可能根本不需要压缩。如果你这样做了,那么你可能不想使用 zip 格式,它是过时的技术,有相当大的缺点,显然你有一些相当具体的需求。您可能需要 ZStandard (zstd)。
压缩是如何工作的
压缩的工作原理是查看一个字节块并在其中找到某种形式的重复。因此,无法压缩单个字节。
这使得这项工作从根本上与并行化不一致:如果您采用 100 万字节的 blob 并将其压缩为 10 个 100k 字节的块,分别压缩每个 miniblob,然后任何重复,其中一个重复在一个 miniblob 中,另一个在另一个 miniblob 中,意味着您错过了压缩数据的机会,如果您将这些数据压缩到一个 blob 中,您将不会错过。
ZIP确实让你稍微并行化的唯一原因是因为它是一种旧格式 - 在当时是明智的,但在这个时代,ZIP 格式的几乎每个部分都是垃圾.
为什么 ZIP 不好?
ZIP 好坏参半,将两个不相关的工作混为一谈。
-
捆绑器。捆绑工具是一些软件,它获取一堆文件并将其转换为单个流(单个字节袋)。为此,捆绑工具将获取有关文件的元数据(其名称、其所有者/组或其他访问信息、其最后修改时间等)以及其中的数据,并将其序列化为单个流。 zip 这样做,例如posix tar 工具。
-
压缩机。压缩器获取数据流并通过查找重复模式对其进行压缩。
zip 本质上只是#1,但作为捆绑程序的一部分,带有“此文件中的数据”的部分有一个标志,表明压缩算法已应用于表示数据的字节。理论上您几乎可以使用任何算法,但在实践中,每个 zip 文件都有所有 条目使用 DEFLATE 算法压缩,这远不如更现代的算法。
.tar.gz 是完全相同的技术(首先捆绑它:tar 文件,然后 gzip 该 tar 文件。gzip 是 DEFLATE 算法),但在某些情况下效率更高(它将压缩应用于整个流而不是重新启动每个文件都从头开始。如果你拿 1000 个类似的小文件,那么 .tar.gz 格式的文件比 .zip 格式的文件小几个数量级。
此外,zip 是旧的,它在当时做出的选择是可辩护的,但在现代系统中却很愚蠢:您不能“流式传输”zip(在收到整个文件之前,您无法有意义地开始解压),因为捆绑器的信息位于文件的末尾。
那么为什么我可以并行化 zip?
因为 zip 会在每个文件上“重新启动”压缩窗口。这是低效的,并且会损害 zip 文件的压缩率。
如果需要,您可以将完全相同的原则应用于任何数据块。用压缩效率换取并行性。 ZIP 是一种没有用处的格式;正如你所说,如果你有一个大得多的文件,那就没有意义了。
'restart window at' 是一个可以推广的原则,并且各种压缩格式以更有用的方式支持它(每 X 个字节重新启动,而不是 ZIP 不可靠的'在每个文件处重新启动')。
什么是瓶颈?
发送数据涉及多个方面:源提供您要发送的字节的速度,字节被处理成然后可以发送的包的速度(例如zip工具,但可以任何东西,包括只是逐字发送,未压缩),打包字节传输到目标系统的速度,目标可以解压它的速度,以及目标可以处理解压结果的速度.
您确定压缩方面是瓶颈吗?
在基本情况下,您从硬盘读取字节,压缩它们,通过住宅互联网管道将它们发送到另一个系统,该系统解压缩并将它们保存在 HDD 上,很可能是瓶颈是网络。并行化压缩步骤完全是一种浪费,实际上只会通过降低压缩率来减慢速度。
如果您是从旋转盘片读取文件,那么源的速度可能是瓶颈,并且并行处理会大大减慢速度:您现在要求读取头弹跳,这比一次性顺序读取数据要慢很多。
如果你有一个快速的源和一个快速的管道,那么瓶颈无疑是压缩和解压缩,但解决方案是根本不压缩:如果你正在传输数据SSD 或从连接 USB3 的字节喷射传感器通过 10M CAT6 电缆将其从一个千兆以太网端口传输到另一个,那么为什么要压缩呢?只需发送这些字节。压缩不会让它变得更快,只要你不使那个 1Gb 连接饱和,你尝试压缩它绝对没有任何收获。
如果您的管道速度较慢,那么让事情变得更快的唯一方法就是尽可能多地压缩。其中最肯定涉及不使用 DEFLATE 算法(例如,不要使用 zip)。使用另一种算法并对其进行配置以获得更好的压缩率,但代价是 CPU 性能。并行化是无关紧要的;这不是瓶颈,所以这样做没有任何意义。
结论
您很可能希望通过未压缩的方式发送文件,或者通过 ZStandard 发送您的文件,根据需要调整压缩与速度的比率。我不知道 java 本身有任何 ZStandard (zstd) impl,但 zstd-jni 项目为您提供了一个基于 java 的 API 来调用 C zstd 库。
如果您坚持使用 ZIP,答案是相当基本的“不,您不能真正做到这一点”,尽管理论上您可以编写一个压缩能力更差但并行性更好的并行 ZIP 压缩器(通过重新启动窗口除了在每个文件上强制重新启动之外,在单个文件中用于更大的文件),并生成仍然与地球上几乎所有解压缩工具兼容的 ZIP 文件。我不知道有一个,我不认为存在一个,而自己编写一个绝对不是微不足道的练习。