您的位置:首页 > 其它

使用zlib压缩和解压gzip

2015-01-07 17:02 453 查看
基于zlib,写了两个函数,可以压缩和解压gzip格式的char *数据。

main里面进行了一下包装,实现了压缩和解压gzip文件的功能。

linux上的标准gzip程序会将原始文件名记录在gzip文件的起始处,后面的内容则同下面程序的操作结果完全相同。所以标准gzip的压缩结果总是比下面程序的压缩结果多几个字节,不过这几个字节不影响解压。

如果需要成功编译该程序,可能需要修改下面zlib头文件的位置到你的环境中的正确位置。

/*************************************************************************** *
* Copyright (c) 2015 Xxx.com, Inc. All Rights Reserved
*
**************************************************************************/

/**
* @file main.cpp
* @author xxx(com@xxx.com)
* @date 2015/01/07 11:46:57
* @brief
*
**/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <zlib.h> // "zlib.h" ?

#define windowBits 15
#define ENABLE_ZLIB_GZIP 32
#define GZIP_ENCODING 16

/**
* @brief
* @param dest_len big enough to hold the result
*/
int decompress (unsigned char *src, size_t src_len, unsigned char *dest, size_t dest_len)
{
z_stream strm;

strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.next_in = src;
strm.avail_in = src_len;
strm.next_out = dest;
strm.avail_out = dest_len;
if (inflateInit2 (& strm, windowBits | ENABLE_ZLIB_GZIP) < 0){
printf("init failed\n");
return -1;
}
if (inflate (& strm, Z_NO_FLUSH) < 0){
printf("inflate failed %s\n", "");
return -1;
}
inflateEnd (& strm);
return dest_len - strm.avail_out;
}
/**
* @brief
* @param
*/
int compress (unsigned char *src, size_t src_len, unsigned char *dest, size_t dest_len)
{
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree  = Z_NULL;
strm.opaque = Z_NULL;
if (deflateInit2 (&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
windowBits | GZIP_ENCODING, 8,
Z_DEFAULT_STRATEGY) < 0){
printf("init failed\n");
return -1;
}

strm.next_in = src;
strm.avail_in = src_len;

strm.avail_out = dest_len;
strm.next_out = dest;
if (deflate (& strm, Z_FINISH) < 0){
printf("deflate failed\n");
return -1;
}
deflateEnd (& strm);
return dest_len - strm.avail_out;
}

int main(int argc, char *argv[])
{
if (argc != 4) {
printf("format error\n\tformat: %s [d|c] inputfile outputfile\n\tuse 'd' for decompress, 'c' for compress\n", argv[0]);
return -1;
}

// get input & output file name
const char * input_file_name = argv[2];
const char * output_file_name = argv[3];

// open input file, and get the size of the file
FILE * fp = fopen (input_file_name, "rb");
if (!fp){
printf("open file failed\n");
return -1;
}
fseek(fp, 0, SEEK_END);
int file_len = ftell(fp);
printf("file len %d\n", file_len);
fseek(fp, 0, SEEK_SET);

// allocate enough memory to hold the input file
unsigned char *src;
src = (unsigned char*)malloc(file_len);

// load the input file
int bytes_read = fread (src, 1, file_len, fp);
fclose(fp);
if (bytes_read != file_len){
printf("read file error[%d != %d]\n", bytes_read, file_len);
free(src);
return -1;
}

// allocate enough memory to hold the result
int dest_len;
if (argv[1][0] == 'd'){
dest_len = file_len * 10;
}else{
dest_len = file_len;
}
unsigned char *dest;
dest = (unsigned char*)malloc(dest_len);

// do the work
int size;
if (argv[1][0] == 'd'){
size = decompress(src, file_len, dest, dest_len);
}else{
size = compress(src, file_len, dest, dest_len);
}

// save the result to the given output file
printf("out len %d\n", size);
if (size > 0){
fp = fopen(output_file_name, "wb");
fwrite(dest, 1, size, fp);
fclose(fp);
}else{
printf("operation failed[code = %d]\n", size);
}

// free resources
free(src);
free(dest);
return 0;

}

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: