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) 将用户信息数据库文件和用户 ...
随机推荐
- JS检查是否支持Storage
查看效果:http://hovertree.com/code/html5/q69kvsi6.htm 代码: <!DOCTYPE html> <html> <head> ...
- 5G
前世 1G 2G 3G 4G 今生 5G 推荐书籍: Gold Smith -<无线通信> David Tse -<无线通信基础> 参考:
- cron表达式详解[转]
Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: Seconds Minutes Hours DayofMonth Month ...
- C#中正则表达式在replace中的应用!
多少年来,许多的编程语言和工具都包含对正则表达式的支持,.NET基础类库中包含有一个名字空间和一系列可以充分发挥规则表达式威力的类,而且它们也都与未来的Perl 5中的规则表达式兼容. 此外, ...
- iis配置出现处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”问题
最近重新由于一些问题要安装vs2015和oracle所以就重装了电脑,吧项目发布到本地的iis上的时候出现问题了, 像之前出现的问题一般都是重装电脑后,安装vs的时候,是先安装了vs,之后再Windo ...
- [函数] Delphi FMX Windows 取得下载 Downloads 目录
在 Firemonkey 提供了一个跨平台的函数 TPath.GetDownloadsPath 来取得该平台的下载目录,但是非常奇怪的是,在 Windows 平台下,取得的下载目录确是: C:\Use ...
- ahjesus web动态icon
刚刚逛插件无意间发现的,记录下,里面有demo可以直接run了看效果 http://nicolasbize.com/faviconx/ http://www.miaofree.com/
- 高性能 TCP & UDP 通信框架 HP-Socket v3.2.3
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- kmdjs指令大全
调试 通过下面方式,可以输出kmdjs声称的类: <script src="../dist/kmd.js?debug" data-main="js/main&quo ...
- 政府应急平台之GIS一张图-flex/java
开发语言是flex.java,开发平台是myeclise.eclise,后台数据库是oracel或sqlserver,开发接口是arcgis api for flex,提供以下的功能: 1.视频监控: ...