我正在尝试压缩某些数据,但也会将数据集拆分为多个存档,这样就不会有任何单个zip文件最终大于某个最大值。
由于我的数据不是来自文件系统,因此使用流媒体方法似乎是个好主意。我想我可以简单地一次编写一个原子数据,同时在写入每个部分之前跟踪流的位置。一旦超出限制,我会在写入不适合的部分之前将流截断到该位置,然后继续创建下一个存档。
我尝试过使用System.IO.Compression中的类 - 创建一个存档,创建一个条目,使用ZipArchiveEntry.Open来获取一个流,然后写入该流。问题是,无论如何都无法从中获取存档的大小。
我可以读取流的位置,但这是跟踪未压缩的字节。截断流也可以正常工作,所以我现在按预期工作,但有一个重要的例外,即限制适用于每个存档有多少未压缩数据,而不是压缩存档的大小。
数据是部分可压缩文本和各种blob(来自最终用户的附件),有时是非常可压缩的,有时根本不可压缩。
我的问题:
1)deflate算法有什么东西与我的方法本身有冲突吗?我知道这是一个基于块的压缩方案,我想这个算法可能无法决定如何编码压缩数据,直到指定了整个存档。
2)如果上面(1)的答案是“是”,那么什么是不会引入太多开销的好策略?
我的一个想法是假设压缩数据不会大于未压缩数据。然后,我可以写入流,直到未压缩的数据超过阈值,然后保存存档,计算阈值和当前大小之间的差异,并重复直到满。
如果不清楚,请说限制为1MB。我写了1 MB的未压缩数据并保存存档。然后我看到生成的存档是0.3MB。我再次打开存档(及其唯一的条目)并以0.7 MB的新限制重新开始,因为我知道我能够在不超调的情况下添加至少那么多未压缩的数据。我想这种方法实现起来相对简单,并且会测试它,但我很想知道是否有人有更好的想法。
答案 0 :(得分:0)
通过查看基础Length
的{{1}}或Position
,您可以找到压缩数据有多大的下限。然后,您可以决定停止添加条目。 ZIP流类往往缓冲不太多。可能大约64KB。
应该可以在某一点截断档案。尝试在测量基本流的FileStream
之前刷新ZIP流。这在理论上总是可行的,但您使用的实际库可能不支持它。测试它或查看源。