我正在使用来自Qt的zlib库对从http服务器收到的gzip数据进行解压缩。因为qUncompress不好,所以我遵循了这里给出的建议:Qt quncompress gzip data,并创建了我自己的方法来解压缩gzip数据,如下所示:
QByteArray gzipDecompress( QByteArray compressData )
{
//strip header
compressData.remove(0, 10);
const int buffer_size = 16384;
quint8 buffer[buffer_size];
z_stream cmpr_stream;
cmpr_stream.next_in = (unsigned char *)compressData.data();
cmpr_stream.avail_in = compressData.size();
cmpr_stream.total_in = 0;
cmpr_stream.next_out = buffer;
cmpr_stream.avail_out = buffer_size;
cmpr_stream.total_out = 0;
cmpr_stream.zalloc = Z_NULL;
cmpr_stream.zfree = Z_NULL;
cmpr_stream.opaque = Z_NULL;
int status = inflateInit2( &cmpr_stream, -8 );
if (status != Z_OK) {
qDebug() << "cmpr_stream error!";
}
QByteArray uncompressed;
do {
cmpr_stream.next_out = buffer;
cmpr_stream.avail_out = buffer_size;
status = inflate( &cmpr_stream, Z_NO_FLUSH );
if (status == Z_OK || status == Z_STREAM_END)
{
QByteArray chunk = QByteArray::fromRawData((char *)buffer, buffer_size - cmpr_stream.avail_out);
uncompressed.append( chunk );
}
else
{
inflateEnd(&cmpr_stream);
break;
}
if (status == Z_STREAM_END)
{
inflateEnd(&cmpr_stream);
break;
}
}
while (cmpr_stream.avail_out == 0);
return uncompressed;
}如果解压缩的数据适合输出缓冲区,那么一切似乎都很好。小于16KB)。如果没有,则第二次调用inflate将返回一个Z_DATA_ERROR。我确信数据是正确的,因为如果输出缓冲区足够大,相同的数据块就会被正确地解压缩。
服务器不会返回包含未压缩数据大小的头文件(只返回压缩数据的大小),所以我遵循了zlib:http://www.zlib.net/zlib_how.html中的使用说明
他们做的和我做的一模一样。你知道我会错过什么吗?在第一次迭代之后,流中的next_in和avail_in成员似乎已正确更新。哦,如果它有用的话,那么发出数据错误时的错误消息是:“距离太远无效”。
有什么想法吗?谢谢。
发布于 2011-04-21 20:10:57
Deflate/Inflate压缩/解压缩算法使用32Kb循环缓冲区。因此,如果解压缩的数据大于16Kb,则16Kb的缓冲区永远不能工作。(严格来说并非如此,因为允许将数据拆分成块,但您需要假设其中可能有32Kb的块。)因此,只需设置buffer_size = 32768,就可以了。
https://stackoverflow.com/questions/5741657
复制相似问题