c++ - zlib 不同解压大小

标签 c++ zlib

我正在尝试使用 zlib 进行解压。我查看了 zlib 站点上的一个教程,并且 inflate 代码产生了不同大小的输出。

int CZLib::Inflate() {
    int ret;
    unsigned int have;
    z_stream zstream;
    unsigned char in[CHUNK];
    unsigned char out[CHUNK];

    zstream.zalloc = Z_NULL;
    zstream.zfree = Z_NULL;
    zstream.opaque = Z_NULL;
    zstream.avail_in = 0;
    zstream.next_in = Z_NULL;
    ret = inflateInit(&zstream);
    if (ret != Z_OK)
        return ret;

    do {
        zstream.avail_in = fread(in, 1, CHUNK, fin);
        if (ferror(fin)) {
            (void)inflateEnd(&zstream);
            return Z_ERRNO;
        }
        if (zstream.avail_in == 0) break;
        zstream.next_in = in;

        do {
            zstream.avail_out = CHUNK;
            zstream.next_out = out;
            ret = inflate(&zstream, Z_NO_FLUSH);
            assert(ret != Z_STREAM_ERROR);
            switch (ret) {
                case Z_NEED_DICT:
                    ret = Z_DATA_ERROR;
                case Z_DATA_ERROR:
                case Z_MEM_ERROR:
                    (void)inflateEnd(&zstream);
                    return ret;
            }
            have = CHUNK - zstream.avail_out;
            if (fwrite(out, 1, have, fout) != have || ferror(fout)) {
                (void)inflateEnd(&zstream);
                return Z_ERRNO;
            }

        } while (zstream.avail_out == 0);
    } while (ret != Z_STREAM_END);

    (void)inflateEnd(&zstream);
    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}

其他

int CZLib::Inflate(const std::string& src) {
    std::vector<char> output;

    z_stream zstream;
    zstream.zalloc = Z_NULL;
    zstream.zfree = Z_NULL;
    zstream.opaque = Z_NULL;
    zstream.avail_in = 0;
    zstream.next_in = Z_NULL;

    int ret = inflateInit(&zstream);
    if (ret != Z_OK)
        return ret;

    unsigned char in[CHUNK];
    unsigned char out[CHUNK];

    int have = 0, nByte = CHUNK, off = 0, remaining = src.size();

    if (src.size() < CHUNK) nByte = src.size();
    do {
        memcpy(in, &src[off], nByte);
        off += nByte;
        remaining -= nByte;

        if (nByte > 0) zstream.avail_in = nByte;

        if (remaining > CHUNK) { nByte = CHUNK; }
        else { nByte = remaining; }

        if (zstream.avail_in == 0) break;
        zstream.next_in = in;

        do {
            zstream.avail_out = CHUNK;
            zstream.next_out = out;

            ret = inflate(&zstream, Z_NO_FLUSH);
            have = CHUNK - zstream.avail_out;
            output.insert(output.end(), out, out + have);

        } while (zstream.avail_out == 0);
    } while (ret != Z_STREAM_END);

    CFile* file = new CFile("in.out", "wb");
    file->Write<char>(&output[0], output.size());
    delete file;
    return ret;
}

它使用相同的数据。其中一个读取磁盘上的文件,另一个使用内存(缓冲方法)。 CHUNK 大小 16384。第一个代码产生 524288(0x80000) 和其他 524800 (0x80200) 字节。差异是 512 字节。为什么会这样?

最佳答案

在第一个代码示例中有这一行

zstream.avail_in = fread(in, 1, CHUNK, fin);

然后你有

if (zstream.avail_in == 0) break;

停止循环。

在第二个代码示例中,您有相同的行来停止循环,但您还有这一行:

    if (nByte > 0) zstream.avail_in = nByte;
        ^^^^^^^^^
        So you only assign to zstream.avail_in when nByte > 0

    ....
    ....

    if (zstream.avail_in == 0) break;
        ^^^^^^^^^^^^^^^^
        Consequently this will not be true when nByte is zero and the
        code will not exit

试试这个:

    zstream.avail_in = nByte;  // Unconditional assignment

    ....

    if (zstream.avail_in <= 0) break;  // Less or equal to zero

关于c++ - zlib 不同解压大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39555457/

相关文章:

c++ - 在不指定基类名称的情况下在派生类中调用基类方法

c++ - 为什么linux上一个动态链接的可执行文件在自己的内存空间里有libc的完整内存空间?

c++ - 创建一个非预定义大小的数组?

json - 解压缩 Gzip JSON 响应

python - 当我尝试使用easy_install时,它显示无法解压数据; zlib 不可用

zlib - 不能不安装分发,zlib

c - iowin32.h 中的 OF 宏

c++ - Enable_if 作为模板参数

sql-server - 给定一个字节数组,我如何找出使用了哪种压缩算法?

c++ - C++中的分号是什么?