首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Qt解压gzip数据时出错

使用Qt解压gzip数据时出错
EN

Stack Overflow用户
提问于 2011-04-21 16:43:01
回答 1查看 3.8K关注 0票数 3

我正在使用来自Qt的zlib库对从http服务器收到的gzip数据进行解压缩。因为qUncompress不好,所以我遵循了这里给出的建议:Qt quncompress gzip data,并创建了我自己的方法来解压缩gzip数据,如下所示:

代码语言:javascript
复制
 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成员似乎已正确更新。哦,如果它有用的话,那么发出数据错误时的错误消息是:“距离太远无效”。

有什么想法吗?谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-04-21 20:10:57

Deflate/Inflate压缩/解压缩算法使用32Kb循环缓冲区。因此,如果解压缩的数据大于16Kb,则16Kb的缓冲区永远不能工作。(严格来说并非如此,因为允许将数据拆分成块,但您需要假设其中可能有32Kb的块。)因此,只需设置buffer_size = 32768,就可以了。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5741657

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档