0

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

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

    #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;
    }
    
  2. 使用inflate*(输出只有 11 个字节):

    #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 使用示例zpipe.c,我根据这个 zlib gzip 讨论inflateInit(&strm);只更改了to的调用,但现在我不知道它为什么会失败,任何人都可以帮忙吗?inflateInit2(&strm, 16 + 15);

4

1 回答 1

0

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

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

于 2013-07-26T14:51:38.503 回答