C解压缩gzip数据

我在网上找到两种方法,还没来得及试,明天就要用,所以先上墙。


#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zlib.h"

#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
#  include <fcntl.h>
#  include <io.h>
#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
#  define SET_BINARY_MODE(file)
#endif

#define CHUNK 16384

/* Decompress from file source to file dest until stream ends or EOF.
   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
   allocated for processing, Z_DATA_ERROR if the deflate data is
   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
   the version of the library linked do not match, or Z_ERRNO if there
   is an error reading or writing the files.
*/
int inf(FILE *source, FILE *dest)
{
    int ret;
    unsigned have;
    z_stream strm;
    unsigned char in[CHUNK];     // A
    unsigned char out[CHUNK];

    /* allocate inflate state */
    strm.zalloc = Z_NULL;        // B
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.avail_in = 0;
    strm.next_in = Z_NULL;
    ret = inflateInit(&strm);    // C
    if (ret != Z_OK)
        return ret;

    /* decompress until deflate stream ends or end of file */
    do {
        strm.avail_in = fread(in, 1, CHUNK, source);     // D
        if (ferror(source)) {
            (void)inflateEnd(&strm);      // E
            return Z_ERRNO;
        }
        if (strm.avail_in == 0)           // F
            break;
        strm.next_in = in;                // G


        /* run inflate() on input until output buffer not full */
        do {
            strm.avail_out = CHUNK;       // H
            strm.next_out = out;

            ret = inflate(&strm, Z_NO_FLUSH);  // I
            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;     // J
            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
                (void)inflateEnd(&strm);    
                return Z_ERRNO;
            }

        } while (strm.avail_out == 0);         // K

        /* done when inflate() says it's done */
    } while (ret != Z_STREAM_END);             // L

    /* clean up and return */
    (void)inflateEnd(&strm);
    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}


第二种方法


static const unsigned char gzipMagicBytes[] = { 0x1f, 0x8b, 0x08, 0x00 };

static const int testElemSize = sizeof(unsigned char);
static const int testElemCount = sizeof(gzipMagicBytes);

const char *fn = "foo.bar";
FILE *fp = fopen(fn, "rbR");
char testMagicBuffer[testElemCount] = {0};
unsigned long long testMagicOffset = 0ULL;

if (fp != NULL) {
    do {
        if (memcmp(testMagicBuffer, gzipMagicBytes, sizeof(gzipMagicBytes)) == 0) {
            /* we found gzip magic bytes, do stuff here... */
            fprintf(stdout, "gzip stream found at byte offset: %llu\n", testMagicOffset);
            break;
        }
        testMagicOffset += testElemSize * testElemCount;
        fseek(fp, testMagicOffset - testElemCount + 1, SEEK_SET);
        testMagicOffset -= testElemCount + 1;
    } while (fread(testMagicBuffer, testElemSize, testElemCount, fp));
}

fclose(fp);




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值