【发布时间】:2011-04-21 08:43:00
【问题描述】:
我正在使用 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;
}
如果解压缩的数据适合输出缓冲区(即小于 16 Kb),一切似乎都可以正常工作。如果没有,第二次调用 inflate 将返回 Z_DATA_ERROR。我确信数据是正确的,因为如果输出缓冲区足够大,则可以正确解压缩相同的数据块。
服务器没有返回带有未压缩数据大小的标头(只有压缩数据的大小),所以我按照 zlib 中的使用说明进行操作:http://www.zlib.net/zlib_how.html
他们做的正是我正在做的事情。知道我可能会错过什么吗?流中的 next_in 和avail_in 成员似乎在第一次迭代后正确更新。哦,如果有用的话,发出数据错误时的错误消息是:“invalid distance too far back”。
有什么想法吗?谢谢。
【问题讨论】:
标签: qt compression gzip