zoukankan      html  css  js  c++  java
  • zlib压缩一个文件为gzip格式

    网上有很多针对zlib的总结,但是很零散,自己经过总结,实现了用zlib压缩一个文件为gzip格式,似的可以直接使用winr工具解压。

    具体方法是使用zlib的deflate系列函数,将buffer压缩为gzip格式,deflateInit2的参数注意使用MAX_WBITS+16,这样压缩后可以带gzip的头、尾信息。

    然后将压缩后的内容直接写入到目标文件,保存为.gz, 使用WinR就可以直接解压了。

    demo程序如下(deflate_gzip.c):

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <zlib.h>
      4  
      5 /*******************************************************************************
      6 * Compress gzip data
      7 * @parm[data] data buffer to be compressed
      8 * @parm[dlen] data buffer length
      9 * @parm[zdata] data buffer to save the compressed datas
     10 * @parm[zdlen] compressed data buffer length
     11 * return: 0 - OK; -1 - FAIL 
     12 *******************************************************************************/ 
     13 int gzcompress(Bytef *data, uLong dlen, Bytef *zdata, uLong *zdlen)
     14 {
     15     int err = 0;
     16     z_stream c_stream;
     17     
     18     printf("%s: data=%p, dlen=%lu, zdata=%p, *zdlen=%lu\n",
     19         __func__, data, dlen, zdata, *zdlen);
     20     
     21     if(data && dlen > 0) 
     22     {
     23         c_stream.zalloc = NULL;
     24         c_stream.zfree = NULL;
     25         c_stream.opaque = NULL;
     26         //use parm 'MAX_WBITS+16' so that gzip headers are contained
     27         if(deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
     28             MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY) != Z_OK) 
     29         {
     30             printf("%s: deflateinit2 failed!\n",__func__);
     31             return -1;
     32         }
     33         c_stream.next_in  = data;
     34         c_stream.avail_in  = dlen;
     35         c_stream.next_out = zdata;
     36         c_stream.avail_out  = *zdlen;
     37         while(c_stream.avail_in != 0 && c_stream.total_out < *zdlen)
     38         {
     39             if(deflate(&c_stream, Z_NO_FLUSH) != Z_OK) {
     40                 printf("%s: deflate failed!\n",__func__);
     41                 return -1;
     42             }
     43         }
     44         if(c_stream.avail_in != 0) {
     45             printf("%s: avail_in not zero!\n",__func__);
     46             return c_stream.avail_in;
     47         }
     48         for(;;) 
     49         {
     50             if((err = deflate(&c_stream, Z_FINISH)) == Z_STREAM_END)
     51                 break;
     52             if(err != Z_OK) {
     53                 printf("%s: deflate finish fail: %d\n",__func__, err);
     54                 return -1;
     55             }
     56         }
     57         if(deflateEnd(&c_stream) != Z_OK) {
     58             printf("%s: deflate end failed!\n",__func__);
     59             return -1;
     60         }
     61         *zdlen = c_stream.total_out;
     62         return 0;
     63     }
     64     return -1;
     65 }
     66 
     67 /*******************************************************************************
     68 * Compress a file into a gzip file
     69 * @parm[input_name] the file path to be compressed
     70 * @parm[output_name] output path of compressed gzip file
     71 * return: 0 - OK; -1 - FAIL 
     72 *******************************************************************************/ 
     73 int compress_file_to_gzip(char * input_name, char * output_name)
     74 {
     75     FILE *fp = NULL;
     76     uLong flen, clen;
     77     unsigned char * fbuf = NULL;
     78     unsigned char * cbuf = NULL;
     79     char def_output_name[PATH_MAX] = {0};    
     80 
     81     if((fp = fopen(input_name, "rb")) == NULL)
     82     {
     83         printf("%s: can not open %s!\n", __func__, input_name);
     84         return -1;
     85     }
     86     
     87     /*load file content to buffer*/
     88     fseek(fp, 0L, SEEK_END);
     89     flen = ftell(fp);
     90     fseek(fp, 0L, SEEK_SET);
     91     fbuf = (unsigned char *)malloc(flen * sizeof(unsigned char));
     92     if(NULL == fbuf){
     93         printf("%s: no enough memory!\n", __func__);
     94         goto __error;
     95     }
     96     fread(fbuf, sizeof(unsigned char), flen, fp);
     97     fclose(fp);
     98     fp = NULL;
     99     
    100     /*compute compressBound*/
    101     clen = compressBound(flen);
    102     cbuf = (unsigned char *)malloc(clen * sizeof(unsigned char));
    103     if(NULL == cbuf) {
    104         printf("%s: no enough memory!\n", __func__);
    105         goto __error;
    106     }
    107     
    108     if(gzcompress(fbuf, flen, cbuf, &clen))
    109     {
    110         printf("%s: compress %s failed!\n", __func__, input_name);
    111         goto __error;
    112     }
    113 
    114     if(NULL == output_name) {
    115         snprintf(def_output_name, sizeof(def_output_name),
    116         "%s.gz", input_name);
    117         output_name = def_output_name;
    118     }
    119     if((fp = fopen(output_name, "wb")) == NULL)
    120     {
    121         printf("%s: can not open %s!\n", __func__, output_name);
    122         goto __error;
    123     }
    124     fwrite(cbuf, sizeof(unsigned char), clen, fp);
    125     
    126     fclose(fp);
    127     free(fbuf);
    128     free(cbuf);
    129     return 0;
    130 
    131 __error:
    132     if(fp) fclose(fp);
    133     if(fbuf) free(fbuf);
    134     if(cbuf) free(cbuf);
    135     return -1;
    136 }
    137 
    138 int main(int argc, char * argv[])
    139 {
    140     if(argc < 2) {
    141         printf("too few args!\n");
    142         return 0;
    143     }
    144 
    145     if(argc < 3) {
    146         return compress_file_to_gzip(argv[1],NULL);
    147     }
    148 
    149     return compress_file_to_gzip(argv[1], argv[2]);
    150 }

    编译命令:

    gcc -o zlibtest deflate_gzip.c.c -lz

    如果编译连接的时候示找不到deflate等函数,则需要安装zlib库,ubuntu下:

    sudo apt-get install zlib1g zlib1g-dev zlibc

    参考内容链接:

    http://www.oschina.net/code/snippet_65636_22542

    http://blog.csdn.net/turingo/article/details/8178510

  • 相关阅读:
    bootstrap
    bootstrap
    IDEA 配置maven
    jQuery
    jQuery
    jQuery
    jQuery
    Jquery
    【k8s】Pod-metadata
    【k8s】terminationMessagePolicy
  • 原文地址:https://www.cnblogs.com/yanghaizhou/p/5268692.html
Copyright © 2011-2022 走看看