0

標準の gzip ヘッダーを含む gzip ファイルのサンプルがあります。zlibの関数で1F 8B 08 00 ...それを膨らませるとinflate*、出力はわずか 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;
    }
    

実際、2 番目のスニペットは公式の zlib の使用例zpipe.cからのものです。この zlib gzip の議論に従って、inflateInit(&strm);への呼び出しのみを変更しましたが、失敗する理由がわかりません。誰か助けてください。inflateInit2(&strm, 16 + 15);

4

1 に答える 1

0

inf()これは、 gzipZ_OKストリームが正常に解凍され、検証されていることを意味します。

「出力はわずか11バイトです」とはどういう意味ですか? inf()関数はまったく出力を生成できません。

于 2013-07-26T14:51:38.503 に答える