zlib介紹
zlib是提供數(shù)據(jù)壓縮用的函式庫颗味,由Jean-loup Gailly與Mark Adler所開發(fā)嫁蛇,初版0.9版在1995年5月1日發(fā)表芬膝。zlib使用DEFLATE算法谷徙,最初是為libpng函式庫所寫的伞剑,后來普遍為許多軟件所使用。此函式庫為自由軟件胆数,使用zlib授權(quán)
配置
我是從網(wǎng)上直接下載了zlib的dll文件的,壓縮包具體有幾個(gè)部分互墓,分別是頭文件zconf.h,zlib.h必尼;lib文件zdll.lib;dll文件zlib1.dll。
配置過程很簡單判莉,包含頭文件目錄或引入頭文件豆挽;配置VS的工程屬性頁,在鏈接器-常規(guī)-附加庫目錄券盅,添加lib文件所在目錄帮哈,同時(shí)在鏈接器-輸入-附加依賴項(xiàng),添加zdll.lib锰镀;最后將zlib1.dll放到Debug目錄和exe文件在一起就可以了娘侍。
例子
#include <stdio.h>
#include "zlib.h"
int main()
{
/* 原始數(shù)據(jù) */
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;
}
輸出結(jié)果是:
Src string:hello world! aaaaa bbbbb ccccc ddddd 中文測試 yes
Length:50
After Compressed Length:49
After UnCompressed Length:50
UnCompressed String:hello world! aaaaa bbbbb ccccc ddddd 中文測試 yes
這里,zlib只是把一段內(nèi)存壓縮泳炉,壓縮后放的另一段內(nèi)存上憾筏,這離壓縮文件甚至文件夾的目標(biāo)還很遠(yuǎn)。
確切的說花鹅,zlib可能并不是一個(gè)針對ZIP文件的庫氧腰,它只是一個(gè)針對gzip以及deflate算法的庫。它提供了一個(gè)叫做minizip (contrib\minizip) 例子來給出操作 ZIP 文件的方法刨肃。
Minizip
Minizip是一個(gè)Zip和UnZip文件的附加實(shí)例古拴。minizip.c和miniunz.c分別實(shí)際的壓縮、解壓程序真友,除去其主程序minizip.c和miniunz.c后黄痪,剩下的部分我們可以看作是zlib的一個(gè)上層庫,它封裝了與ZIP文件格式相關(guān)的操作锻狗。
壓縮的具體操作
壓縮涉及到以下api:
- zipOpen64
- zipClose
- zipOpenNewFileInZip
- zipCloseFileInZip
- zipWriteInFileInZip
使用 zipOpen64 來打開/創(chuàng)建一個(gè) ZIP 文件满力,然后開始遍歷要被放到壓縮包中去的文件。針對每個(gè)文件轻纪,先調(diào)用一次 zipOpenNewFileInZip油额,然后開始讀原始文件數(shù)據(jù),使用 zipWriteInFileInZip 來寫入到 ZIP 文件中去刻帚。zipOpenNewFileInZip 的第三個(gè)參數(shù)是一個(gè) zip_fileinfo 結(jié)構(gòu)潦嘶,該結(jié)構(gòu)數(shù)據(jù)可全部置零,其中 dosDate 可用于填入一個(gè)時(shí)間(LastModificationTime)崇众。它的第二個(gè)參數(shù)是 ZIP 中的文件名掂僵,若要保持目錄結(jié)構(gòu),該參數(shù)中可以保留路徑顷歌。
解壓的具體操作
解壓縮涉及到以下api:
- unzOpen64
- unzClose
- unzGetGlobalInfo64
- unzGoToNextFile
- unzGetCurrentFileInfo64
- unzOpenCurrentFile
- unzCloseCurrentFile
- unzReadCurrentFile
打開一個(gè)ZIP文件后锰蓬,需要先使用unzGetGlobalInfo64來取得該文件的一些信息,來了解這個(gè)壓縮包里一共包含了多少個(gè)文件眯漩,等等芹扭。目前我們用得著的就是這個(gè)文件數(shù)目麻顶。然后開始遍歷ZIP中的文件,初始時(shí)自動(dòng)會(huì)定位在第一個(gè)文件舱卡,以后處理完一個(gè)后用unzGoToNextFile來跳到下一個(gè)文件辅肾。對于每個(gè)內(nèi)部文件,可用unzGetCurrentFileInfo64來查內(nèi)部文件名轮锥。這個(gè)文件名和剛才zipOpenNewFileInZip的第二個(gè)參數(shù)是一樣的形式矫钓,所以有可能包含路徑。也有可能會(huì)以路徑分隔符(/)結(jié)尾舍杜,表明這是個(gè)目錄項(xiàng)(其實(shí)壓縮操作的時(shí)候也可以針對目錄寫入這樣的內(nèi)部文件新娜,上面沒有做)。所以接下來要根據(jù)情況創(chuàng)建(多級)目錄蝴簇。unzGetCurrentFileInfo64的第三個(gè)參數(shù)是unz_file_info64結(jié)構(gòu)杯活,其中也有一項(xiàng)包含了dosDate信息,可以還原文件時(shí)間熬词。對于非目錄的內(nèi)部文件旁钧,用 unzOpenCurrentFile,打開互拾,然后unzReadCurrentFile讀取文件內(nèi)容歪今,寫入到真實(shí)文件中。unzReadCurrentFile返回 0 表示文件讀取結(jié)束颜矿。
參考資料
轉(zhuǎn)載請注明作者Jason Ding及其出處
Github主頁(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
簡書主頁(http://www.reibang.com/users/2bd9b48f6ea8/latest_articles)