能否预先压缩数据文件以便稍后插入到 zip 文件中以提高性能?

问题描述 投票:0回答:3

作为我们安装程序构建的一部分,我们必须将数千个大型数据文件压缩到大约十个或二十个“包”中,每个包中有几百个(甚至数千个)文件,这些文件都依赖于与其他文件一起保存包裹。 (如果您愿意的话,它们会一起版本化。)

然后在实际安装过程中,用户选择他们想要包含在系统中的软件包。这还允许他们从我们的网站将软件包的更新作为一个大型版本化文件下载,而不是要求他们下载数千个单独的文件,这也可能导致它们与同一软件包中的其他人不同步。

由于这些是数据文件,其中一些在设计和编码阶段会定期更改,这意味着我们必须重新压缩该特定 zip 包中的所有文件,即使只有一个文件发生了变化。这使得我们的安装程序构建的打包步骤每次都要花费一个多小时,其中大部分将重新压缩我们没有接触过的东西。

我们考虑过单独保留 zip 包,然后替换其中的特定文件,但是从 zip 中间插入和删除大文件并不能给我们带来太大的性能提升。 (一点点,但还不够值得。)

我想知道是否可以将文件预处理为缓存的原始“压缩状态”,该状态与写入 zip 包的方式相匹配,但只有数据本身,而不是 zip 标头信息等。

我的想法是,如果可能的话,在我们的构建步骤中,我们将首先查找任何没有与之关联的压缩缓存的数据文件,如果没有,我们将压缩该文件并将结果写入缓存.

接下来,我们只需将所有缓存一起附加到文件流中,添加文件所需的任何适当的 zip 标头。

这意味着我们仍在每次构建期间重新创建整个 zip,但我们只是重新压缩已更改的数据。其余部分将按原样写入,速度非常快,因为它是直接写入磁盘。如果数据文件发生更改,其缓存将被破坏,因此下一个构建过程将重新创建它。

但是,我不确定这样的事情是否可能。是吗?如果是,是否有任何文档可以说明如何尝试此操作?

c# compression zip
3个回答
3
投票

是的,这是可能的。最直接的方法是将每个文件单独压缩到其自己的关联 zip 存档中,并包含一个条目。修改任何文件时,您可以替换其关联的 zip 文件以使所有文件保持最新。然后,您可以编写一个简单的程序来获取一组单条目 zip 文件并将它们合并到一个 zip 文件中。您需要参考PKZip appnote中的文档。看看那个。

现在您已经阅读了应用说明,您需要做的是使用每个 zip 文件中的本地标头、数据和中央标头,将本地标头和数据按顺序写入新的 zip 文件,然后保存新文件中的中央标头和本地标头的偏移量。然后在新文件的末尾保存当前偏移量,使用您保存的中央标头写入新的中央目录,适当更新偏移量,并以中央目录开头的偏移量作为新的中央目录记录结尾.

更新:

我认为这是一篇足够有用的文章。您可以在这里获取它。


1
投票

您可以事先压缩每个文件,然后将它们“压缩”在一起,最后不进行压缩,以快速将它们聚合到可分发的包中。它的效率不如一次压缩所有数据,但修改速度应该更快。


0
投票

我似乎无法找到实现此类功能的实际 exe。看来我尝试过的大多数具有合并/更新能力的现有工具都会重新处理(压缩)数据流,正如您已经说过的那样。

但是,如果您或某人想写的话,您所描述的似乎是可以完成的。如果您查看此链接以获取 ZIP 文件格式规范,您可以大致了解必须解析和处理的结构。看起来您可以很快地从一个文件转到另一个文件,收集并丢弃感兴趣的文件,然后合并到新的/更新的文件中。您仍然需要在新的目标存档中重建一个新的中央目录(请参阅上述链接文档的第 4.3.6 节)。

经过更多挖掘后,DotNetZip Library 论坛有一条消息询问相同类型的功能,该功能也提供了与我上面描述的描述相同的描述。它还链接到此文档,这似乎表明可以将对此的支持添加到 DotNetZip 库中,供您进一步实验。

© www.soinside.com 2019 - 2024. All rights reserved.