本文介绍了使用zlib的gz *函数解压缩成功,但因inflate *函数解压缩失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用 inflate *对其进行充气时,我有一个带有标准gzip标头 1F 8B 08 00 ... 的gzip文件示例。 zlib中的code>函数,输出只有11个字节(实际上输出应该是4KB),但是当我用 gz * 函数将其解压缩时,它会产生正确的输出,代码为:

I have a gzip file sample, with standard gzip header 1F 8B 08 00 ..., when I inflate it with inflate* functions in zlib, the output is only 11 bytes(in fact the output should be about 4KB), but when I decompress it with gz* functions, it produce the correct output, the code:


  1. 使用 gz * (这样可以产生正确的输出):

  1. using gz* (this can produce correct output):

#define CHUNK 10240
int gz_decompress(const char *path) {
    gzFile f = gzopen(path, "rb");
    if(!f)
        return -1;

    unsigned char result[CHUNK];
    int bytes_read = gzread(f, result, CHUNK);
    if(bytes_read < CHUNK)
        if(!gzeof(f))
            return -2;
    gzclose (f);
    return 0;
}


  • 使用充气* (输出仅11个字节):

  • using inflate* (output is only 11 bytes):

    #define CHUNK 10240
    int inf(FILE *source)
    {
        int ret;
        unsigned have;
        z_stream strm;
        unsigned char in[CHUNK];
        unsigned char out[CHUNK];
    
        /* allocate inflate state */
        strm.zalloc = Z_NULL;
        strm.zfree = Z_NULL;
        strm.opaque = Z_NULL;
        strm.avail_in = 0;
        strm.next_in = Z_NULL;
        // ret = inflateInit(&strm);
        ret = inflateInit2(&strm, 16 + 15);
        if (ret != Z_OK)
            return ret;
    
        /* decompress until deflate stream ends or end of file */
        do {
            strm.avail_in = fread(in, 1, CHUNK, source);
            if (strm.avail_in == 0)
                break;
            strm.next_in = in;
    
            /* run inflate() on input until output buffer not full */
            do {
                strm.avail_out = CHUNK;
                strm.next_out = out;
                ret = inflate(&strm, Z_NO_FLUSH);
                assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
                switch (ret) {
                case Z_NEED_DICT:
                    ret = Z_DATA_ERROR;     /* and fall through */
                case Z_DATA_ERROR:
                case Z_MEM_ERROR:
                    (void)inflateEnd(&strm);
                    return ret;
                }
                have = CHUNK - strm.avail_out;
            } while (strm.avail_out == 0);
    
            /* done when inflate() says it's done */
        } while (ret != Z_STREAM_END);
    
        /* clean up and return */
        (void)inflateEnd(&strm);
        return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
    }
    


  • 实际上,第二个片段来自官方zlib用法示例,我只更改了 inflateInit(& strm); inflateInit2(& strm,16 + 15); 根据,但现在我不知道为什么它会失败,有人可以帮忙吗?

    In fact, the second snippet comes from the official zlib usage example zpipe.c, I changed only the invocation of inflateInit(&strm); to inflateInit2(&strm, 16 + 15); according to this zlib gzip discussion, but now I have no idea why it fails, anyone could help?

    推荐答案

    根据您的评论, inf()返回 Z_OK ,这意味着gzip流已成功解压缩并验证。

    Per your comment, inf() is returning Z_OK, which means that the gzip stream is being successfully decompressed and verified.

    您的意思是输出只有11个字节?您的 inf()函数根本不会产生任何输出。

    What do you mean "output is only 11 bytes"? Your inf() function can produce no output at all.

    这篇关于使用zlib的gz *函数解压缩成功,但因inflate *函数解压缩失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-01 16:35