做软件开发,难免会用到压缩和解压的功能。我最开始用的是xzip这个库,就一个.h和.c文件,很小巧,接口也简单清晰,在codeproject上可以找到:http://www.codeproject.com/Articles/4135/XZip-and-XUnzip-Add-zip-and-or-unzip-to-your-app-w。但是这个库比较老了,2007后就没有更新了。
比较出名开源的压缩解压库是zlib,也一直在更新。很多著名的软件都采用这个库,比如linux内核,apache服务器,chrome浏览器等等。所以我们采用这个库肯定是没错的。下面一zlib 1.2.8来介绍如何在windows上面使用这个库。
编译
从http://www.zlib.net/上下载已经编译好的dll、lib文件,也可以下载代码,直接编译。
要编译zlib的动态库和静态库的话,从visual studio tool里面打开Visual Studio 2008 Command Prompt,切换到zlib-1.2.8目录,在Command Prompt里执行nmake -f win32/Makefile.msc,然就会在zlib-1.2.8目录生成相关的dll和lib文件。
也可以切换到zlib-1.2.8contrib\masmx86目录。从Command Prompt里面执行bld_ml32.bat。然后打开zlib-1.2.8contrib\vstudio,选中对应的vs版本,从vs里面编译相关的工程。
使用
动态库的话需要zdll.lib、zlib1.dll、zconf.h、zlib.h这四个文件,静态库则需要zlib.lib、zconf.h、zlib.h。
zlib.h里面有好几类api。最开始的是Basic Functions,都是一些非常底层的功能实现。Advanced Functions则是更为特别的功能,只有少数程序需要。最后则是Utility Functions,它是那些基础函数的封装,提供了更为简单的接口。一般来说我们使用Utility Functions就足够了。
Utility Functions
Utility Functions有以下几个函数。
// 把源缓冲区的数据压缩到目的缓冲区
// destLen是目的缓冲区大小,大小至少是compressBound(sourceLen)。函数结束后返回压缩后实际的缓冲区大小
// sourceLen是源缓冲区大小
// 成功的时候返回值为Z_OK,Z_MEM_ERROR是没有足够的内存,Z_BUF_ERROR是没有足够的缓冲区
ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
// 前面几个参数与上面一样,后面level是指定压缩等级
// 返回Z_STREAM_ERROR是level值不合法
ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level));
// 返回compress或compress2压缩后的大小
ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
// 解压。返回Z_DATA_ERROR输入压缩数据不合法
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
下面是压缩的例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#include "zlib.h"
#pragma comment(lib, "zlib.lib")
char
sourceBuf
[
]
=
"sdfadsfsdglkjafsdfasdfafsdgdjafsdfasdfafjafsdfasdfafjafsdfasdfafjafsdfasdfafadfasdfgs"
;
int
sourceSize
=
sizeof
(
sourceBuf
)
;
int
destSize
=
compressBound
(
sourceSize
)
;
char
*
destBuf
=
new
char
[
destSize
]
;
_tprintf
(
_T
(
"sourceSize=%d destSize=%dn"
)
,
sourceSize
,
destSize
)
;
int
result
=
compress
(
(
Bytef
*
)
destBuf
,
(
uLongf
*
)
&destSize
,
(
Bytef
*
)
sourceBuf
,
(
uLongf
)
sourceSize
)
;
_tprintf
(
_T
(
"sourceSize=%d destSize=%dn"
)
,
sourceSize
,
destSize
)
;
delete
[
]
destBuf
;
输出:
sourceSize
=
86
destSize
=
99
sourceSize
=
86
destSize
=
39
|
uncompress这个函数不太好用,因为我们不知道解压会需要多大的缓冲区。
zlib没有直接提供文件和目录的压缩相关函数,我们可以使用另外一个别人封装好的库zip.c和zip.h,这个库是基于zlib上面的。
不过说实话,接口超难用。