实现zip格式的内存压缩
2013-02-01 17:37:57| 分类: 编程资料 | 标签: |举报 |字号大中小 订阅
minizip(http://www.winimage.com/zLibDll/minizip.html)只是实现了文件的压缩解压缩,有时我们需要直接对内存的数据进行zip格式的压缩解压缩,本文对此进行了研究。
在minizip的网站上提到了
Justin Fletcher wrote a very simple implementation of a memory access method for the ioapi code (ioapi_mem_c.zip).
也就是说这个人已经实现了内存压缩。
由于zlib是一个要使用于多个平台的库,因此对于IO的操作就是用回调函数的方式来实现的,在不同的平台上使用不同的文件操作函数就可以实现跨平台。
因此对内存的压缩解压缩就是基于此,单独写一些内存操作的函数,模拟文件读写等操作,压缩解压缩最终操作的就是内存,因此就达到了我们的目的。
具体编码测试如下(WIN下,使用VS2008):
1、创建一个控制台工程,将ioapi_mem_c.c文件加入到工程中
2、写如下代码来进行测试
int izipbufsize = 200;
char *zipBuf = new char[izipbufsize];
int ifileBufSize = 100;
char *fileBuf = “1234567890”;
char *newFileName = new char[100];
sprintf(newFileName, “%x+%x”,fileBuf,ifileBufSize);
char *filename = new char[256];
sprintf(filename, “%x+%x”,zipBuf,izipbufsize);
zlib_filefunc_def *pzlib_filefunc_def = new zlib_filefunc_def;
fill_memory_filefunc(pzlib_filefunc_def);
zipFile z1 = zipOpen2(filename, 0, NULL, pzlib_filefunc_def);
zip_fileinfo zi;
zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
zi.dosDate = 0;
zi.internal_fa = 0;
zi.external_fa = 0;
//int iRet = zipOpenNewFileInZip(z1, newFileName, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_NO_COMPRESSION);
int iRet = zipOpenNewFileInZip(z1, newFileName, NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_NO_COMPRESSION);
//int iRet = zipOpenNewFileInZip(z1, newFileName, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
iRet = zipWriteInFileInZip(z1, fileBuf, 10);
iRet = zipCloseFileInZip(z1);
ZPOS64_T t1;
iRet = zipClose(z1,NULL,&t1);
代码说明:
1、由于内存操作没有文件名,因此需要模拟一个文件名,模拟的文件名的格式为内存地址+内存长度,使用16进制。由于以上是测试压缩一个文件,因此需要两块内存区域,一个是需要压缩的数据(filename),一个是压缩后的数据(newFileName)。
2、压缩前后的内存大小要字节控制,压缩还好,压缩后不会大于原来的110%。主要是解压,可以考虑先读取压缩文件的信息来获取压缩率,然后再分配内存大小
3、为了获取压缩后字节的多少,本文修改了zipClose,通过第三个参数返回大小
完整工程:
下载: testzlib.rar