将 GZipStream 结果拆分为给定大小的块以保持其有效

Split a GZipStream result into given sized chunks keeping it valid

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

byte[] input = ...;

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

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

如果我只是拆分结果 byte[],这些块将不再形成有效的 GZip 存档,所以这不是一个好方法。

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

如何在将每个块保存为有效的 GZip 存档的同时执行此操作?

没有有效的方法来执行此操作,因为您无法在不压缩的情况下预测压缩输出的大小。 (除非你没有压缩和一些只有存储块的扩展,但我假设你需要压缩。)

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

您不能保证压缩后的数据完全适合您的块大小,因为添加一个未压缩的字节可能会添加两个压缩的字节,直接跳过您的确切块大小。然而,对于 gzip 格式,您可以作弊并在 header 中添加垃圾字节以将其填充到准确的数量。