zlib的安裝與使用
zlib是一個很好的壓縮解壓縮庫,今天我們分別介紹如何在Linux與Windows上安裝與使用:
一:Linux平台
首先看看自己的機器上是不是已經安裝好zlib了:
whereis zlib
如果安裝好了,會輸出zlib的路徑,這樣直接跳過前2步。
1.
在http://www.zlib.net/下載zlib的最新版,我的是1.2.3(官網貌似上不去,可以找別的地方下載)
2.
解壓,編譯:
./configure
make
sudo make install
3.
zlib安裝好了,下面我們寫一個程式測試一下:
Makefile:
all: test.cgcc -Wall -o test test.c -lzclean:rm -rf *.o test
注意到,我們用-lz加入了zlib庫
test.c
#include <stdio.h>#include <zlib.h>int main(){ /* 未經處理資料 */ unsigned char strSrc[] = "hello world! aaaaa bbbbb ccccc ddddd 中文測試 yes"; unsigned char buf[1024] = {0}; unsigned char strDst[1024] = {0}; unsigned long srcLen = sizeof(strSrc); unsigned long bufLen = sizeof(buf); unsigned long dstLen = sizeof(strDst); printf("Src string:%s\nLength:%ld\n", strSrc, srcLen); /* 壓縮 */ compress(buf, &bufLen, strSrc, srcLen); printf("After Compressed Length:%ld\n", bufLen); /* 解壓縮 */ uncompress(strDst, &dstLen, buf, bufLen); printf("After UnCompressed Length:%ld\n",dstLen); printf("UnCompressed String:%s\n",strDst); return 0;}
4.
運行結果如下所示:
呵呵,只壓縮掉了一個位元組。
我們用到了兩個函數:compress和uncompress:
壓縮:
int compress(unsigned char * dest, unsigned long * destLen, unsigned char * source, unsigned long sourceLen);
dest:壓縮後資料儲存的目標緩衝區
destLen:目標緩衝區的大小(必須在調用前設定,並且它是一個指標)
source:要壓縮的資料
sourceLen:要壓縮的資料長度
compress()函數成功返回Z_OK,如果記憶體不夠,返回Z_MEM_ERROR,如果目標緩衝區太小,返回Z_BUF_ERROR
解壓縮:
int uncompress(unsigned char * dest, unsigned long * destLen, unsigned char * source, unsigned long sourceLen);
dest:解壓後資料儲存的目標緩衝區
destLen:目標緩衝區的大小(必須在調用前設定,並且它是一個指標)
source:要解壓的資料
sourceLen:要解壓的資料長度
uncompress()函數成功返回Z_OK,如果記憶體不夠,返回Z_MEM_ERROR,如果目標緩衝區太小,返回Z_BUF_ERROR,如果要解壓的資料損毀或不完整,返回Z_DATA_ERROR。
二:Windows平台
zlib提供了用VC++6.0編譯的版本,因此我們首先在Windows下編譯zlib的原始碼,然後再用上面的例子測試:
1.
解壓zlib-1.2.3-src.zip(文末有連結),開啟zlib.dsw,直接編譯,提示:
'ml.exe' 不是內部或外部命令,也不是可啟動並執行程式或批次檔。
2.
因為ml.exe是微軟的彙編編譯器,我們不需要,因此:Build-->Set Active Project Configuration,將所有的帶"ASM"的項都去掉,然後選擇Win32 LIB Debug,如:
3.
在zlib classes上右鍵選擇設為啟動項目,然後再編譯,出現如下錯誤:
fatal error C1083: Cannot open include file: 'unistd.h': No such file or directory compress.c
unistd.h是Linux下的檔案,我們不需要,只要將#if 1 改為#if 0即可,如所示:
4.
再編譯,發現出現如下4個錯誤:
error C2059: syntax error : 'bad suffix on number'
error C2146: syntax error : missing ')' before identifier 'L'
error C2198: 'gzseek' : too few actual parameters
error C2059: syntax error : ')'
沒關係,將0LL改為0L即可(即去掉一個L),如:
5.
再編譯,沒有錯誤,如:
6.
zlib編譯好後,會產生zlib1.lib和zlib1.dll兩個檔案,這正是我們需要的。
下面還是用之前的測試程式:
建立一個VC++6工程,加入如下的代碼,並將zlib1.dll拷貝到項目目錄下:
#include <stdio.h>#include "../zlib/include/zlib.h"#pragma comment(lib, "../zlib/lib/zlib1.lib")int main(){ /* 未經處理資料 */ unsigned char strSrc[] = "hello world! aaaaa bbbbb ccccc ddddd 中文測試 yes"; unsigned char buf[1024] = {0}; unsigned char strDst[1024] = {0}; unsigned long srcLen = sizeof(strSrc); unsigned long bufLen = sizeof(buf); unsigned long dstLen = sizeof(strDst); printf("Src string:%s\nLength:%ld\n", strSrc, srcLen); /* 壓縮 */ compress(buf, &bufLen, strSrc, srcLen); printf("After Compressed Length:%ld\n", bufLen); /* 解壓縮 */ uncompress(strDst, &dstLen, buf, bufLen); printf("After UnCompressed Length:%ld\n",dstLen); printf("UnCompressed String:%s\n",strDst); return 0;}
和之前的程式類似,只多了#pragma comment,這裡需要填入zlib1.lib的正確路徑
然後運行,一切正常,如:
呵呵,我們發現同樣的字串在Linux和Windows上長度是不一樣的!
另外還要說的是我們編譯的VC++6.0版的zlib工程中包含一個example樣本程式,可以參考參考。
為了方便大家,本文的所有源碼都可以下載:
http://download.csdn.net/detail/htttw/4340134
下面是網上摘錄的zlib的其他重要函數:
關鍵的函數有那麼幾個:
(1) int compress2 (Bytef *dest, uLongf *destLen,const Bytef *source, uLong sourceLen,int level);
功能和上一個函數一樣,都一個參數可以指定壓縮品質和壓縮數度之間的關係(0-9)不敢肯定這個參數的話不用太在意它,明白一個道理就好了: 要想得到高的壓縮比就要多花時間
(2) uLong compressBound (uLong sourceLen);
計算需要的緩衝區長度. 假設你在壓縮之前就想知道你的產度為 sourcelen 的資料壓縮後有多大, 可調用這個Function Compute一下,這個函數並不能得到精確的結果,但是它可以保證實際輸出長度肯定小於它計算出來的長度
(3) deflateInit() + deflate() + deflateEnd();
3個函數結合使用完成壓縮功能,具體用法看 example.c 的 test_deflate()函數. 其實 compress() 函數內部就是用這3個函數實現的(工程 zlib 的 compress.c 檔案)
(4) inflateInit() + inflate() + inflateEnd()
和(5)類似,完成解壓縮功能.
(5) gz開頭的函數.
用來操作*.gz的檔案,和檔案stdio調用方式類似. 想知道怎麼用的話看example.c 的 test_gzio() 函數,很easy.
(6) 其他諸如獲得版本等函數就不說了.
完成!