博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
zlib压缩一个文件为gzip格式
阅读量:7021 次
发布时间:2019-06-28

本文共 5261 字,大约阅读时间需要 17 分钟。

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

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

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

demo程序如下(deflate_gzip.c):

1 #include 
2 #include
3 #include
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

 

参考内容链接:

转载于:https://www.cnblogs.com/yanghaizhou/p/5268692.html

你可能感兴趣的文章
SQL SERVER发布与订阅
查看>>
oracle行转列遇到的一个问题
查看>>
Fiddler
查看>>
Spring Cloud 之 服务注册与发现
查看>>
集合 小结
查看>>
confluence
查看>>
猜拳游戏案例
查看>>
jquery mouseout和mouseleave区别
查看>>
iOS逆向之fishHook怎么通过符号找字符串
查看>>
WCF-简单 配置文件
查看>>
[GeoServer]重拾GeoServer之安装篇
查看>>
在选择屏幕添加长文本,换行等等 全在这里
查看>>
Dubbo背景和简介
查看>>
网络基础——1
查看>>
scp命令的用法详解
查看>>
JAVA里自定义注解来进行数据验证
查看>>
转://Oracle 数据备份与恢复微实践
查看>>
[转载] 七龙珠第一部——第013话 悟空的大变身
查看>>
隐马尔可夫HMM中viterbi算法
查看>>
UOJ #449. 【集训队作业2018】喂鸽子
查看>>