我正在制作一个简单的C ++应用程序,该应用程序必须将压缩数据发送到我的API。 API会在同样经过压缩的应用上触发响应。 我必须解压缩它。我正在使用zlib的解压缩功能,但我不知道数据有多大。 有人可以帮我解决这个问题吗? 如何计算和设置目标缓冲区的大小?
答案 0 :(得分:1)
我认为文档对此非常清楚
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
将源缓冲区解压缩到目标缓冲区。 sourceLen 是源缓冲区的字节长度。 在输入时,destLen是 目标缓冲区的总大小,必须足够大以 保存所有未压缩的数据。 (未压缩数据的大小 必须事先由压缩机保存并传输到 通过此机制范围之外的某种机制进行解压缩 压缩库。)退出时,destLen是 未压缩的数据。
如果成功,uncompress返回Z_OK,否则返回Z_MEM_ERROR 足够的内存,如果输出中没有足够的空间,则Z_BUF_ERROR 缓冲区,如果输入数据已损坏或不完整,则返回Z_DATA_ERROR。 如果没有足够的空间,uncompress()将填充 输出缓冲区,未压缩数据到该点为止。
因此zlib建议发送未压缩的大小以及压缩的流。
但是我们也可以注意到句子
在没有足够空间的情况下,uncompress()会使用直到该点为止的未压缩数据填充输出缓冲区。
因此,您可以在开头的压缩消息中包含长度。然后在您的目标位置开始使用小缓冲区解压缩。它可能不会将所有内容解压缩到小缓冲区中。但是,如果您一开始就将其解压缩,则足以读取数据长度。然后,您可以使用它来分配/调整目标缓冲区的大小,然后再次使用uncompress。
根据您的用例,这可能是个好主意。如果您的消息大小没有太大变化,并且程序运行时间更长,那么最好只维护一个目标缓冲区,然后根据需要增加该目标缓冲区。
答案 1 :(得分:0)
作为速度优化,如果您愿意进行冗余调用以偶尔解压缩,则可以预测下一个调用的目标缓冲区大小。 通常情况下,给定流中的数据段大约以相同的因子压缩。例如,文本通常会压缩2到3倍。 因此,请在某处记录目标缓冲区的最后大小。然后,为下一个解压缩调用分配相同的数量。如果太小(Z_BUF_ERROR),则增加缓冲区大小并重复。如果缓冲区空间过多,就没有问题;只需减小下一个通话的大小即可。
这是附加的优化。假设您的目标将非常大,例如千兆字节。而且您不想浪费CPU周期来进行试用解压缩。您只能提供源数据的前几百KB,然后查看它会扩展多少。然后相应地分配实际的目标缓冲区。我不知道uncompress()是否可以让您这样做,但inflate()可以。