本文仅仅简单介绍如何对字符串做gzip压缩和解压缩,关于如何处理文件以及其他高级用法参考官方帮助手册,或者下面的中译版。
具体代码如下:
#include <iostream> #include <string> #include <zlib.h> using namespace std; int compress(const char * src, int srcLen, char * dst, int dstLen) { z_stream strm; //初始化strm结构中的zalloc, zfree, opaque,要求使用默认的内存分配策略 strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; //设置输入输出缓冲区 strm.avail_in = srcLen; strm.avail_out = dstLen; strm.next_in = (Bytef *)src; strm.next_out = (Bytef *)dst; int err = -1; //初始化zlib的状态,成功返回Z_OK //deflateInit:zlib格式,deflateInit2:gzip格式 // err = deflateInit(&strm, Z_DEFAULT_COMPRESSION); err = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS+16, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); if (err == Z_OK) { //Z_FINISH表明完成输入,让deflate()完成输出 err = deflate(&strm, Z_FINISH); //Z_STREAM_END表明所有的输入都已经读完,所有的输出也都产生 if (err == Z_STREAM_END) { //deflateEnd释放资源,防止内存泄漏 (void)deflateEnd(&strm); cout << "compression succed, before compression size is " << strm.total_in << " after compressione size is " << dstLen - strm.avail_out << endl; //strm.avail_out表明输出缓冲区剩余的空闲空间大小 return dstLen - strm.avail_out; } else { (void)deflateEnd(&strm); cout << "compression failed, deflate return: " << err << endl; return -1; } } else { (void)deflateEnd(&strm); cout << "compression initialization failed, quit!" << endl; return 0; } } int decompress(const char * src, int srcLen, char * dst, int dstLen) { z_stream strm; strm.zalloc = NULL; strm.zfree = NULL; strm.opaque = NULL; strm.avail_in = srcLen; strm.avail_out = dstLen; strm.next_in = (Bytef *)src; strm.next_out = (Bytef *)dst; int err = -1; err = inflateInit2(&strm, MAX_WBITS+16); //err = inflateInit(&strm); if (err == Z_OK) { err = inflate(&strm, Z_FINISH); if (err == Z_STREAM_END) { (void)inflateEnd(&strm); cout << "decompress succed, before decompress size is " << strm.total_in << " after decompress size is " << strm.total_out << endl; return strm.total_out; } else { (void)inflateEnd(&strm); cout << "decompression failed, inflate return: " << err << endl; return -1; } } else { inflateEnd(&strm); cout << "decompression initialization failed, quit!" << endl; return 0; } } int main(int argc, char const *argv[]) { string str = "zlib is designed to be a free, general-purpose, legally unencumbered -- that is, not covered by any patents -- lossless data-compression library for use on virtually any computer hardware and operating system. The zlib data format is itself portable across platforms. Unlike the LZW compression method used in Unix compress(1) and in the GIF image format, the compression method currently used in zlib essentially never expands the data. (LZW can double or triple the file size in extreme cases.) zlib's memory footprint is also independent of the input data and can be reduced, if necessary, at some cost in compression. A more precise, technical discussion of both points is available on another page."; unsigned int len = str.size(); int res = -1; char buf[65536]; char buf_[65536]; res = compress(str.c_str(), len, buf, sizeof(buf)); res = decompress(buf, res, buf_, sizeof(buf_)); buf_[res] = 0; cout << buf_ << endl; return 0; }
编译:
g++ test_zlib.cpp -o test_zlib -L/usr/lib/i386-linux-gnu -lz
输出:
compression succed, before compression size is 703 after compressione size is 422 decompress succed, before decompress size is 422 after decompress size is 703 zlib is designed to be a free, general-purpose, legally unencumbered -- that is, not covered by any patents -- lossless data-compression library for use on virtually any computer hardware and operating system. The zlib data format is itself portable across platforms. Unlike the LZW compression method used in Unix compress(1) and in the GIF image format, the compression method currently used in zlib essentially never expands the data. (LZW can double or triple the file size in extreme cases.) zlib's memory footprint is also independent of the input data and can be reduced, if necessary, at some cost in compression. A more precise, technical discussion of both points is available on another page.
评论