zlib压缩一个文件为gzip格式
网上有很多针对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格式的更多相关文章
- gulp插件实现压缩一个文件夹下不同目录下的js文件(支持es6)
gulp-uglify:压缩js大小,只支持es5 安装: cnpm: cnpm i gulp-uglify -D yarn: yarn add gulp-uglify -D 使用: 代码实现1:压缩 ...
- 下载zip格式文件(压缩Excel文件为zip格式)
Mongodb配置文件参考这一篇:http://www.cnblogs.com/byteworld/p/5913061.html package util; import java.io.Buffer ...
- 在Ubuntu下如何压缩一个文件夹
.gz 解压1:gunzip FileName.gz解压2:gzip -d FileName.gz 压缩:gzip FileName .tar.gz 解压:tar zxvf FileName.tar. ...
- Android下文件的压缩和解压(Zip格式)
Zip文件结构 ZIP文件结构如下图所示, File Entry表示一个文件实体,一个压缩文件中有多个文件实体. 文件实体由一个头部和文件数据组,Central Directory由多个File he ...
- 压缩打包介绍、gzip、bzip2、xz压缩工具
第5周第1次课(4月16日) 课程内容: 6.1 压缩打包介绍6.2 gzip压缩工具6.3 bzip2压缩工具6.4 xz压缩工具 6.1 压缩打包介绍 为什么要给文件进行压缩呢?首先压缩和不压缩空 ...
- qt 调用zlib压缩与解压缩功能
Zlib是一种免费且通用的压缩库,由于Zlib压缩效果比LZW好,而且解压缩速度快,更重要的是商业软件中使用Zlib不需要缴纳版权费,所以很多游戏都使用Zlib压缩资源文件. Zlib是由Jean-l ...
- Java实现文件压缩与解压[zip格式,gzip格式]
Java实现ZIP的解压与压缩功能基本都是使用了Java的多肽和递归技术,可以对单个文件和任意级联文件夹进行压缩和解压,对于一些初学者来说是个很不错的实例. zip扮演着归档和压缩两个角色:gzip并 ...
- 解压gzip格式文件(包括网页)
先上源码 参数说名: - source :gzip格式流内容. - len: gzip流长度 - dest: 解压后字符流指针 - gzip: 压缩标志,非0时解压gzip格式,否则按照zip解压 说 ...
- Linux基础------文件打包解包---tar命令,文件压缩解压---命令gzip,vim编辑器创建和编辑正文件,磁盘分区/格式化,软/硬链接
作业一:1) 将用户信息数据库文件和组信息数据库文件纵向合并为一个文件/1.txt(覆盖) cat /etc/passwd /etc/group > /1.txt2) 将用户信息数据库文件和用户 ...
随机推荐
- iOS面试用到的知识点和技术点--第二章
接着第一章的继续 昨天没有更新,很抱歉 1.Socket编程 以及一些第三方框架Socket-IO GCDAsyncSocket通信框架? 1.使用系统自带的CFsocket 2.第三方Socket ...
- c# json序列化 意外字符i 意外字符ï 解决方案
今天使用DataContractJsonSerializer遇到了这个问题 这是个蛋疼的问题,折腾了我好久,反复检查对象和json字符串,没发现什么问题,而且错误提示还看走眼了,是ï不是i 现公布解决 ...
- Lind.DDD.Domain.IOwnerBehavor对实体的意义
回到目录 对于Lind.DDD架构,我之前写了不少文章,对于它的Domain模式也介绍了不少,像之前的IEntity,ILogicDeleteBehavor,IModifyBehavor,IStatu ...
- 通过Laravel 初识Vue.js
最近也在学习laravel的框, 因为之前学过tp框架, 都说laravel是最优雅的框架,所以开学后忍不住去试试这个在国外已经火的不要不要的框架. 总的来说,对于学习完tp框架后,我觉得tp毕竟是中 ...
- js中的位运算
按位运算符是把操作数看作一系列单独的位,而不是一个数字值.所以在这之前,不得不提到什么是"位": 数值或字符在内存内都是被存储为0和 1的序列,每个0和1被称之为1个位,比如说10 ...
- 1-2 nodejs小节 文件读取
1.表达式 在命令行输入 node回车后,可以在后边输入相应的表达式,进行运算操作 2.阻塞文件读取 var data=fs.readFileSync('input.txt', 'utf-8') ...
- Intent属性详解二 Action、Category
先看效果图: 1.Action:该activity可以执行的动作 该标识用来说明这个activity可以执行哪些动作,所以当隐式intent传递过来action时,如果跟这里<intent-fi ...
- LruCache缓存
LruCache通常用于实现内存缓存,采用的缓存算法是LRU(Least Recently Used)即近期最少使用算法,其核心思想是:当缓存满的时候,会优先淘汰那些近期最少使用的缓存对象. 1.Lr ...
- iOS AFNetworking内存泄漏处理方法
iOS AFN内存泄漏处理方法 细心的你是否也发现AFN的内存泄漏的问题了呢. 在这里给大家提供一个解决AFN内存泄漏的方法. 单例解决AFN内存泄漏 + (AFHTTPSessionManager ...
- 解决 安装cocoapods失败,提示 requires Ruby version >=2.2.2
步骤如下: rvm install ruby-2.2 但是,但是竟然报错了,具体我忘记额,但是是权限和brew的问题,那么我又转向修复brew: // 清理原来brew rm -rf /usr/loc ...