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

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

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

demo程序如下(deflate_gzip.c):

 #include <stdio.h>
#include <stdlib.h>
#include <zlib.h> /*******************************************************************************
* Compress gzip data
* @parm[data] data buffer to be compressed
* @parm[dlen] data buffer length
* @parm[zdata] data buffer to save the compressed datas
* @parm[zdlen] compressed data buffer length
* return: 0 - OK; -1 - FAIL
*******************************************************************************/
int gzcompress(Bytef *data, uLong dlen, Bytef *zdata, uLong *zdlen)
{
int err = ;
z_stream c_stream; printf("%s: data=%p, dlen=%lu, zdata=%p, *zdlen=%lu\n",
__func__, data, dlen, zdata, *zdlen); if(data && dlen > )
{
c_stream.zalloc = NULL;
c_stream.zfree = NULL;
c_stream.opaque = NULL;
//use parm 'MAX_WBITS+16' so that gzip headers are contained
if(deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
MAX_WBITS + , , Z_DEFAULT_STRATEGY) != Z_OK)
{
printf("%s: deflateinit2 failed!\n",__func__);
return -;
}
c_stream.next_in = data;
c_stream.avail_in = dlen;
c_stream.next_out = zdata;
c_stream.avail_out = *zdlen;
while(c_stream.avail_in != && c_stream.total_out < *zdlen)
{
if(deflate(&c_stream, Z_NO_FLUSH) != Z_OK) {
printf("%s: deflate failed!\n",__func__);
return -;
}
}
if(c_stream.avail_in != ) {
printf("%s: avail_in not zero!\n",__func__);
return c_stream.avail_in;
}
for(;;)
{
if((err = deflate(&c_stream, Z_FINISH)) == Z_STREAM_END)
break;
if(err != Z_OK) {
printf("%s: deflate finish fail: %d\n",__func__, err);
return -;
}
}
if(deflateEnd(&c_stream) != Z_OK) {
printf("%s: deflate end failed!\n",__func__);
return -;
}
*zdlen = c_stream.total_out;
return ;
}
return -;
} /*******************************************************************************
* Compress a file into a gzip file
* @parm[input_name] the file path to be compressed
* @parm[output_name] output path of compressed gzip file
* return: 0 - OK; -1 - FAIL
*******************************************************************************/
int compress_file_to_gzip(char * input_name, char * output_name)
{
FILE *fp = NULL;
uLong flen, clen;
unsigned char * fbuf = NULL;
unsigned char * cbuf = NULL;
char def_output_name[PATH_MAX] = {}; if((fp = fopen(input_name, "rb")) == NULL)
{
printf("%s: can not open %s!\n", __func__, input_name);
return -;
} /*load file content to buffer*/
fseek(fp, 0L, SEEK_END);
flen = ftell(fp);
fseek(fp, 0L, SEEK_SET);
fbuf = (unsigned char *)malloc(flen * sizeof(unsigned char));
if(NULL == fbuf){
printf("%s: no enough memory!\n", __func__);
goto __error;
}
fread(fbuf, sizeof(unsigned char), flen, fp);
fclose(fp);
fp = NULL; /*compute compressBound*/
clen = compressBound(flen);
cbuf = (unsigned char *)malloc(clen * sizeof(unsigned char));
if(NULL == cbuf) {
printf("%s: no enough memory!\n", __func__);
goto __error;
} if(gzcompress(fbuf, flen, cbuf, &clen))
{
printf("%s: compress %s failed!\n", __func__, input_name);
goto __error;
} if(NULL == output_name) {
snprintf(def_output_name, sizeof(def_output_name),
"%s.gz", input_name);
output_name = def_output_name;
}
if((fp = fopen(output_name, "wb")) == NULL)
{
printf("%s: can not open %s!\n", __func__, output_name);
goto __error;
}
fwrite(cbuf, sizeof(unsigned char), clen, fp); fclose(fp);
free(fbuf);
free(cbuf);
return ; __error:
if(fp) fclose(fp);
if(fbuf) free(fbuf);
if(cbuf) free(cbuf);
return -;
} int main(int argc, char * argv[])
{
if(argc < ) {
printf("too few args!\n");
return ;
} if(argc < ) {
return compress_file_to_gzip(argv[],NULL);
} return compress_file_to_gzip(argv[], argv[]);
}

编译命令:

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

zlib压缩一个文件为gzip格式的更多相关文章

  1. gulp插件实现压缩一个文件夹下不同目录下的js文件(支持es6)

    gulp-uglify:压缩js大小,只支持es5 安装: cnpm: cnpm i gulp-uglify -D yarn: yarn add gulp-uglify -D 使用: 代码实现1:压缩 ...

  2. 下载zip格式文件(压缩Excel文件为zip格式)

    Mongodb配置文件参考这一篇:http://www.cnblogs.com/byteworld/p/5913061.html package util; import java.io.Buffer ...

  3. 在Ubuntu下如何压缩一个文件夹

    .gz 解压1:gunzip FileName.gz解压2:gzip -d FileName.gz 压缩:gzip FileName .tar.gz 解压:tar zxvf FileName.tar. ...

  4. Android下文件的压缩和解压(Zip格式)

    Zip文件结构 ZIP文件结构如下图所示, File Entry表示一个文件实体,一个压缩文件中有多个文件实体. 文件实体由一个头部和文件数据组,Central Directory由多个File he ...

  5. 压缩打包介绍、gzip、bzip2、xz压缩工具

    第5周第1次课(4月16日) 课程内容: 6.1 压缩打包介绍6.2 gzip压缩工具6.3 bzip2压缩工具6.4 xz压缩工具 6.1 压缩打包介绍 为什么要给文件进行压缩呢?首先压缩和不压缩空 ...

  6. qt 调用zlib压缩与解压缩功能

    Zlib是一种免费且通用的压缩库,由于Zlib压缩效果比LZW好,而且解压缩速度快,更重要的是商业软件中使用Zlib不需要缴纳版权费,所以很多游戏都使用Zlib压缩资源文件. Zlib是由Jean-l ...

  7. Java实现文件压缩与解压[zip格式,gzip格式]

    Java实现ZIP的解压与压缩功能基本都是使用了Java的多肽和递归技术,可以对单个文件和任意级联文件夹进行压缩和解压,对于一些初学者来说是个很不错的实例. zip扮演着归档和压缩两个角色:gzip并 ...

  8. 解压gzip格式文件(包括网页)

    先上源码 参数说名: - source :gzip格式流内容. - len: gzip流长度 - dest: 解压后字符流指针 - gzip: 压缩标志,非0时解压gzip格式,否则按照zip解压 说 ...

  9. Linux基础------文件打包解包---tar命令,文件压缩解压---命令gzip,vim编辑器创建和编辑正文件,磁盘分区/格式化,软/硬链接

    作业一:1) 将用户信息数据库文件和组信息数据库文件纵向合并为一个文件/1.txt(覆盖) cat /etc/passwd /etc/group > /1.txt2) 将用户信息数据库文件和用户 ...

随机推荐

  1. JS美女图片切换带视觉差

    使用JS实现,多张图片动态切换查看效果:http://hovertree.com/texiao/js/21/ 效果图: 转自:http://hovertree.com/h/bjaf/iamhxcyk. ...

  2. Wijmo 2016 V3发布

    互操作性增强 Wijmo继续扩展互操作性包括Angular 2.ReactJS和VueJS. 模块支持 Wijmo最初设计为单个模块. 一切都存储在Wijmo命名空间.Wijmo现在包含很多不同的模块 ...

  3. 从零开始学 Java - 利用 Nginx 负载均衡实现 Web 服务器更新不影响访问

    还记得那些美妙的夜晚吗 你洗洗打算看一个小电影就睡了,这个时候突然想起来今天晚上是服务器更新的日子,你要在凌晨时分去把最新的代码更新到服务器,以保证明天大家一觉醒来打开网站,发现昨天的 Bug 都不见 ...

  4. Linq的分页与组合查询的配合使用

    1.首先使用Linq连接数据库,并扩展属性 public partial class User { public string SexStr { get { string end = "&l ...

  5. var a=function()跟function a()的区别

    //代码一: a(); //执行这个会报错 var a = function(index){ alert(index); } a(); //执行这个不会报错 //代码二: a(); //执行这个不会报 ...

  6. css3制作旋转立方体相册

    首先让我们来看一下最终效果图: 当鼠标放在图片上是介个样子滴: 是不是觉得很好看?那接下来就一起制作吧! 我个人觉得编程,首先是思路,然后是代码,一起分析一下这个效果的思路. 1.背景颜色,它属于一种 ...

  7. jQuery静态方法noop,camelCase,nodeName,trim使用和源码分析

    noop方法 jQuery.noop()函数是一个空函数,它什么也不做. 当某些时候你需要传入函数参数,而且希望它什么也不做的时候,你可以使用该函数,也无需再新建一个空的函数. 示例: // 传入一个 ...

  8. 学习zepto.js(对象方法)[5]

    继续说. clone: 该方法不接收任何参数,会返回对象中的所有元素集合,但不会对象绑定的事件. var $temp = $("div").clone(); //并不接收任何参数. ...

  9. SAP Fiori和UI5的初学者导航

    你是UI5和Fiori的新手?来对地方了. 对我来说,今年是不得不“跟上时代”去提升自己ABAP世界以外的技术技能的困难的一年.幸运的是,有很多可免费获得的信息和课程可以帮你实现这个跳跃.不要等着别人 ...

  10. AndroidTV版(乐视超3 X55)root,将自己的软件设置为开机自启、系统软件,卸载系统应用等问题总结

    最近开发android软件客户要安装在乐视TV上,而且要求是开机自启.我很天真的以为写一个广播接收类接收开机广播就可以了,可是根本不会,有的设备就是不可以接收到开机广播,于是各种百度搜索.大神们说是只 ...