C++内嵌代码使用压缩的方法(compress和uncompress函数)需要有zlib,编译时加-lz
2011-04-01 23:30
2051 查看
转自:http://blog.csdn.net/Solstice/archive/2003/04/04/2061.aspx
以下全文转:
使用zlib库里的compress函数与uncompress函数
zlib 是通用的压缩库,提供了一套 in-memory 压缩和解压函数,并能检测解压出来的数据的完整性(integrity)。zlib 也支持读写 gzip (.gz) 格式的文件。下面介绍两个最有用的函数——compress 和 uncompress。
int compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
compress函数将 source 缓冲区中的内容压缩到 dest 缓冲区。 sourceLen 表示source 缓冲区的大小(以字节计)。注意函数的第二个参数 destLen 是传址调用。当调用函数时,destLen表示 dest 缓冲区的大小,destLen > (sourceLen + 12)*100.1%。当函数退出后,destLen 表示压缩后缓冲区的实际大小。此时 destLen / sourceLen 正好是压缩率。
compress 若成功,则返回 Z_OK;若没有足够内存,则返回 Z_MEM_ERROR;若输出缓冲区不够大,则返回 Z_BUF_ERROR。
int uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
uncompress 函数将 source 缓冲区的内容解压缩到 dest 缓冲区。sourceLen 是 source 缓冲区的大小(以字节计)。注意函数的第二个参数 destLen 是传址调用。当调用函数时,destLen 表示 dest 缓冲区的大小, dest 缓冲区要足以容下解压后的数据。在进行解压缩时,需要提前知道被压缩的数据解压出来会有多大。这就要求在进行压缩之前,保存原始数据的大小(也就是解压后的数据的大小)。这不是 zlib 函数库的功能,需要我们做额外的工作。当函数退出后, destLen 是解压出来的数据的实际大小。
uncompress 若成功,则返回 Z_OK ;若没有足够内存,则返回 Z_MEM_ERROR;若输出缓冲区不够大,则返回 Z_BUF_ERROR。若输入数据有误,则返回 Z_DATA_ERROR。
zlib 带的 example.c 是个很好的学习范例,值得一观。我们写个程序,验证 zlib 的压缩功能。所写的测试程序保存为 testzlib.cpp ,放在 zlib-1.1.4 目录下。程序源代码:
// testzlib.cpp 简单测试 zlib 的压缩功能
#include <cstring>
#include <cstdlib>
#include <iostream>
#include "zlib.h"
using namespace std;
int main()
{
int err;
Byte compr[200], uncompr[200]; // big enough
uLong comprLen, uncomprLen;
const char* hello = "12345678901234567890123456789012345678901234567890";
uLong len = strlen(hello) + 1;
comprLen = sizeof(compr) / sizeof(compr[0]);
err = compress(compr, &comprLen, (const Bytef*)hello, len);
if (err != Z_OK) {
cerr << "compess error: " << err << '/n';
exit(1);
}
cout << "orignal size: " << len
<< " , compressed size : " << comprLen << '/n';
strcpy((char*)uncompr, "garbage");
err = uncompress(uncompr, &uncomprLen, compr, comprLen);
if (err != Z_OK) {
cerr << "uncompess error: " << err << '/n';
exit(1);
}
cout << "orignal size: " << len
<< " , uncompressed size : " << uncomprLen << '/n';
if (strcmp((char*)uncompr, hello)) {
cerr << "BAD uncompress!!!/n";
exit(1);
} else {
cout << "uncompress() succeed: /n" << (char *)uncompr;
}
}
编译执行这个程序,输出应该是
D:/libpng/zlib-1.1.4>bcc32 testzlib.cpp zlib.lib
D:/libpng/zlib-1.1.4>testzlib
orignal size: 51 , compressed size : 22
orignal size: 51 , uncompressed size : 51
uncompress() succeed:
12345678901234567890123456789012345678901234567890
PS:这两个函数的一个很好的用处便是当需要将一个很占内存的变量写入文件以节省内存时,可以先压缩一下,然后写入文件,当需要使用时再从文件中读出,然后解压缩,以便节省IO时间。此外,有些情况可能还要序列化一下,当要压缩的内存不是一段连续的内存的时候。
相关文章推荐
- C++内嵌代码使用压缩的方法(compress和uncompress函数)需要有zlib,编译时加-lz
- zlib库compress和uncompress函数的使用方法
- C++ 压缩文件及文件夹方法 使用zlib开源库
- 1 开发一个注重性能的JDBC应用程序不是一件容易的事. 当你的代码运行很慢的时候JDBC驱动程序并不会抛出异常告诉你。 本系列的性能提示将为改善JDBC应用程序的性能介绍一些基本的指导原则,这其中的原则已经被许多现有的JDBC应用程序编译运行并验证过。 这些指导原则包括: 正确的使用数据库MetaData方法 只获取需要的数据 选用最佳性能的功能 管理连
- C++使用Mysql的详细步骤及各个常用方法的代码演示:select,insert,update,delete
- 使用doxygen从c++代码中生成文档的方法学习 .
- 【Android学习笔记】如何使用Eclipse在Android项目中调用C/C++代码,及遇到的错误解决方法
- 4000 C++使用Mysql的详细步骤及各个常用方法的代码演示:select,insert,update,delete
- C++ - "shared_ptr"的使用方法 及 代码
- Linux下使用Eclipse编译C/C++代码时遇到问题的说明
- 简谈用g++编译运行c++代码流程,以及动态库静态库的创建与使用
- 使用doxygen从c++代码中生成文档的方法学习 .
- ubuntu下 c++代码调试需要使用-gstabs+选项
- 减少C++代码编译时间的方法
- 使用Themeleaf时, HTML内嵌的JS代码需要注意< 和 >的问题
- 减少C++代码编译时间的方法
- 使用VC6.0编译C++代码的时候报错:fatal error C1071: unexpected end of file found in comment(Mark ZZ)
- cublas中执行矩阵乘法运算的函数 首先要注意的是cublas使用的是以列为主的存储方式,和c/c++中的以行为主的方式是不一样的。处理方法可参考下面的注释代码
- C++ - "shared_ptr"的使用方法 及 代码
- 在C++中使用sqlite的示例(从下载、编译、工程建立、配置、测试代码编写全方位介绍)