C/C++ 用zlib解压gzip文件

25 篇文章 0 订阅

见示例:

其中调用inflate()后,zlib会保存解压进程,avail_in,next_in会更新,保存解压进程的断点。avail_out == 0说明这次输出内存用完,数据可能还没解压完,需要继续调用inflate(), 会从上次的位置继续解压。

#include <stdio.h>
/* For "exit". */
#include <stdlib.h>
/* For "strerror". */
#include <string.h>
/* For "errno". */
#include <errno.h>
#include <zlib.h>

/* CHUNK is the size of the memory chunk used by the zlib routines. */

#define CHUNK 0x4000

/* The following macro calls a zlib routine and checks the return
   value. If the return value ("status") is not OK, it prints an error
   message and exits the program. Zlib's error statuses are all less
   than zero. */

#define CALL_ZLIB( x )                                                                             \
    {                                                                                              \
        int status;                                                                                \
        status = x;                                                                                \
        if( status < 0 )                                                                           \
        {                                                                                          \
            fprintf( stderr,                                                                       \
                     "%s:%d: %s returned a bad status of %d.\n",                                   \
                     __FILE__,                                                                     \
                     __LINE__,                                                                     \
                     #x,                                                                           \
                     status );                                                                     \
            exit( EXIT_FAILURE );                                                                  \
        }                                                                                          \
    }

/* if "test" is true, print an error message and halt execution. */

#define FAIL( test, message )                                                                      \
    {                                                                                              \
        if( test )                                                                                 \
        {                                                                                          \
            inflateEnd( &strm );                                                                   \
            fprintf( stderr,                                                                       \
                     "%s:%d: " message " file '%s' failed: %s\n",                                  \
                     __FILE__,                                                                     \
                     __LINE__,                                                                     \
                     file_name,                                                                    \
                     strerror( errno ) );                                                          \
            exit( EXIT_FAILURE );                                                                  \
        }                                                                                          \
    }

/* These are parameters to inflateInit2. See
   http://zlib.net/manual.html for the exact meanings. */

#define windowBits 15
#define ENABLE_ZLIB_GZIP 32

int main()
{
    const char*   file_name = "test.gz";
    FILE*         file;
    z_stream      strm = {0};
    unsigned char in[CHUNK];
    unsigned char out[CHUNK];

    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.next_in = in;
    strm.avail_in = 0;
    CALL_ZLIB( inflateInit2( &strm, windowBits | ENABLE_ZLIB_GZIP ) );

    /* Open the file. */

    file = fopen( file_name, "rb" );
    FAIL( !file, "open" );
    while( 1 )
    {
        int bytes_read;
        int zlib_status;

        bytes_read = fread( in, sizeof( char ), sizeof( in ), file );
        FAIL( ferror( file ), "read" );
        strm.avail_in = bytes_read;
        strm.next_in = in;
        do
        {
            unsigned have;
            strm.avail_out = CHUNK;
            strm.next_out = out;
            zlib_status = inflate( &strm, Z_NO_FLUSH );
            switch( zlib_status )
            {
                case Z_OK:
                case Z_STREAM_END:
                case Z_BUF_ERROR:
                    break;

                default:
                    inflateEnd( &strm );
                    fprintf( stderr, "Gzip error %d in '%s'.\n", zlib_status, file_name );
                    return -1;
            }
            have = CHUNK - strm.avail_out;
            fwrite( out, sizeof( unsigned char ), have, stdout );
        } while( strm.avail_out == 0 );
        if( feof( file ) )
        {
            inflateEnd( &strm );
            break;
        }
    }
    FAIL( fclose( file ), "close" );
    return 0;
}

Ref:

https://www.lemoda.net/c/zlib-open-read/

https://www.zlib.net/manual.html

你可以使用zlib库来解压gzip字符串。以下是一个示例代码: ```c++ #include <iostream> #include <string> #include <zlib.h> int main() { std::string compressed_data = "H4sIAAAAAAAAADWQywrCMAxF9yWw2w7H+P/yuEiZ7UQtjK0Lgk8pLiZvvXWvjZ0IaRbG4ni8v7Pf5vfu7PpfwMjH3j5mOj7zjJc9/f4/6oGtT3LJq6mfa1LWVz4eWjzU1Iy2h2rY1K3aLzR1c5+3qWVZ1kz1a3m5d8Xu7W3M5cZmz2L7pB7T7vB1yN5hK8zZVZaLjTm8v1hX6r5+M2+T0FfVfS1J8zW2+wsAAAA=="; std::string decompressed_data; // Initialize zlib stream z_stream stream; stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; stream.avail_in = 0; stream.next_in = Z_NULL; int ret = inflateInit2(&stream, 15 + 32); if (ret != Z_OK) { std::cerr << "Failed to initialize zlib stream\n"; return 1; } // Inflate the compressed data stream.avail_in = compressed_data.size(); stream.next_in = (Bytef *)compressed_data.data(); char outbuffer[32768]; bool done = false; while (!done) { stream.avail_out = 32768; stream.next_out = (Bytef *)outbuffer; ret = inflate(&stream, Z_NO_FLUSH); switch (ret) { case Z_NEED_DICT: case Z_DATA_ERROR: case Z_MEM_ERROR: inflateEnd(&stream); std::cerr << "Failed to decompress data\n"; return 1; } decompressed_data.append(outbuffer, 32768 - stream.avail_out); if (stream.avail_out != 0) { done = true; } } // Clean up inflateEnd(&stream); std::cout << "Decompressed data: " << decompressed_data << "\n"; return 0; } ``` 在这个示例中,我们将gzip数据解压缩成字符串并打印。请注意,此示例仅适用于gzip数据。如果您要解压缩其他压缩格式(例如zlib或deflate),您需要使用不同的初始化选项。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值