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 中文測(cè)試 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 中文測(cè)試 yes
Length:50
After Compressed Length:49
After UnCompressed Length:50
UnCompressed String:hello world! aaaaa bbbbb ccccc ddddd 中文測(cè)試 yes
這里,zlib只是把一段內(nèi)存壓縮,壓縮后放的另一段內(nèi)存上,這離壓縮文件甚至文件夾的目標(biāo)還很遠(yuǎn)。
確切的說,zlib可能并不是一個(gè)針對(duì)ZIP文件的庫,它只是一個(gè)針對(duì)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 文件,然后開始遍歷要被放到壓縮包中去的文件。針對(duì)每個(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è)文件。對(duì)于每個(gè)內(nèi)部文件,可用unzGetCurrentFileInfo64來查內(nèi)部文件名。這個(gè)文件名和剛才zipOpenNewFileInZip的第二個(gè)參數(shù)是一樣的形式,所以有可能包含路徑。也有可能會(huì)以路徑分隔符(/)結(jié)尾,表明這是個(gè)目錄項(xiàng)(其實(shí)壓縮操作的時(shí)候也可以針對(duì)目錄寫入這樣的內(nèi)部文件,上面沒有做)。所以接下來要根據(jù)情況創(chuàng)建(多級(jí))目錄。unzGetCurrentFileInfo64的第三個(gè)參數(shù)是unz_file_info64結(jié)構(gòu),其中也有一項(xiàng)包含了dosDate信息,可以還原文件時(shí)間。對(duì)于非目錄的內(nèi)部文件,用 unzOpenCurrentFile,打開,然后unzReadCurrentFile讀取文件內(nèi)容,寫入到真實(shí)文件中。unzReadCurrentFile返回 0 表示文件讀取結(jié)束。
參考資料
轉(zhuǎn)載請(qǐng)注明作者Jason Ding及其出處
Github主頁(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
簡書主頁(http://www.itdecent.cn/users/2bd9b48f6ea8/latest_articles)