0

我正在使用zlib中发布的 gzip 代码的想法。对于初始化,我使用deflateInit2(p_strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY). 我正在压缩流。每个数据包都有Z_FULL_FLUSH,除了我使用的最后一个Z_FINISH。压缩每个数据包后,我正在重新排序数据包。

数据包中的数据 ---> [zip] ---> [重新排序] ---> ...

如果我在压缩后膨胀数据,我会在压缩前得到确切的文件。如果我在对数据包重新排序后膨胀数据(同样:每个数据包都用 放气Z_FULL_FLUSH,除了最后一个Z_FINISH)我会得到一个与压缩前的原始文件非常相似的文件。不同之处在于文件的末尾:它缺少字节。那是因为当我给它充气时,我收到最后一个数据包的错误(Z_DATA_ERROR)。如果我膨胀,比方说,用 50KB 的块,重新排序后的膨胀文件是与输入相同的文件,小于 <50KB(整个最后一个数据包已经消失,导致错误)。如果我将膨胀块大小减小到 8B,我仍然会得到Z_DATA_ERROR,但现在我在膨胀时丢失的数据更少,(在我的示例中,我缺少原始文件中的一个字节)。

我没有重新排序最后一个数据包(Z_FINISH)。我尝试发送所有数据包,Z_FULL_FLUSH然后发送另一个“空”数据包(只有Z_FINISH10 个字节)。

为什么会这样?如果我使用 Z_FULL_FLUSH,为什么充气机不能正确充气?它还记得放气数据包的顺序吗?

任何信息都会有所帮助,谢谢。

4

2 回答 2

3

由于您使用Z_FULL_FLUSHwhich 在每次刷新时擦除历史记录,您可以重新排序数据包,除了最后一个。您所做Z_FINISH必须是最后一个数据包。但它不需要任何数据。您可以使用 输入最后一个数据包中的所有数据Z_FULL_FLUSH,然后在没有输入数据的情况下执行最后一个数据包 和Z_FINISH。这将允许你在你喜欢的空包之前重新排序包。总是把最后一个放在最后。

原因是 deflate 格式是自终止的,所以最后一段标志着流的结束。如果你将它重新排序到某个地方的中间,那么当它碰到那个数据包时,膨胀就会停止。

gzip header和trailer需要在开头和结尾维护,trailer中的CRC也相应更新。最后的 CRC 校验取决于数据的顺序。

为什么要尝试做你想做的事情?你在优化什么?

于 2013-10-30T04:52:04.690 回答
1

GZip 是一种流式传输协议。压缩取决于流的先前历史。你不能重新排序。

于 2013-10-30T01:06:45.823 回答