c# - 将 GZipStream 结果拆分为给定大小的 block ,保持其有效

标签 c# gzip gzipstream

我在 byte[] 中有一堆数据,我使用像这样的 GZipStream 来压缩它。

byte[] input = ...;

var zipped = new MemoryStream();
using (var zipper = new GZipStream(zipped, CompressionMode.Compress, true)) {
  zipper.Write(input, 0, input.Length);
}

由于我的技术要求,我需要将结果分成 - 比方说 - 50k block ,以便每个 block 都可以解压缩并恢复原始数据的相应 block 。

如果我只是分割结果byte[],这些 block 将不再形成有效的 GZip 存档,因此这不是一个好方法。

我也无法使用某种循环来停止以 block 大小进行压缩,因为不幸的是,GZipStream 无法报告压缩数据的当前长度。当我关闭压缩流时,我只得到长度,但随后我已经有了一个有效的存档,所以我不能从那里继续。

如何在将每个 block 保留为有效的 GZip 存档的同时做到这一点?

最佳答案

没有有效的方法来做到这一点,因为您无法在不压缩的情况下预测压缩输出的大小。 (除非您没有压缩并且仅使用存储 block 进行一些扩展,但我假设您需要压缩。)

您可以查看this example了解如何在固定 block 大小中获得尽可能多的压缩数据。它对每个 block 进行三次压缩以进行拟合。它对压缩数据进行两次解压缩,以估计适合的未压缩数据量,然后重新压缩该猜测。

您无法确保压缩数据完全适合您的 block 大小,因为添加一个未压缩字节可能会添加两个压缩字节,从而跳过您的确切 block 大小。然而,使用 gzip 格式,您可以作弊并在 header 中添加垃圾字节以将其填充到准确的数量。

关于c# - 将 GZipStream 结果拆分为给定大小的 block ,保持其有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45129657/

相关文章:

web-services - 压缩jQuery的Web服务响应

c# - 通过 BinaryReader 将字节数组解压缩为字符串会产生空字符串

c# - 如何确保奥尔良 Cereal 的一致性?

c# - 利用 BackGroundWorker 跨线程调用 Winforms 控件上的 GUI 操作?

asp.net-mvc-4 - MVC4 捆绑 GZIP 和 header

python - 如何在Python中解压已使用gzip压缩的文本?

php - PHP 中的 GZipStream

c# - 异步 FileStream 读取的正确结构

c# - 我如何检查要删除的点?

scala - 如何使用 SBT 下载静态文件并将其添加到项目中