使用Zlib庫進(jìn)行文件的壓縮和解壓

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:

  1. zipOpen64
  2. zipClose
  3. zipOpenNewFileInZip
  4. zipCloseFileInZip
  5. 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:

  1. unzOpen64
  2. unzClose
  3. unzGetGlobalInfo64
  4. unzGoToNextFile
  5. unzGetCurrentFileInfo64
  6. unzOpenCurrentFile
  7. unzCloseCurrentFile
  8. 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é)束颜矿。

參考資料

Minizip

轉(zhuǎn)載請注明作者Jason Ding及其出處
Github主頁(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
簡書主頁(http://www.reibang.com/users/2bd9b48f6ea8/latest_articles)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寄猩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子骑疆,更是在濱河造成了極大的恐慌田篇,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件箍铭,死亡現(xiàn)場離奇詭異泊柬,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)诈火,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門兽赁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冷守,你說我怎么就攤上這事刀崖。” “怎么了拍摇?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵亮钦,是天一觀的道長。 經(jīng)常有香客問我充活,道長蜂莉,這世上最難降的妖魔是什么孙咪? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮巡语,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘淮菠。我一直安慰自己男公,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布合陵。 她就那樣靜靜地躺著枢赔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拥知。 梳的紋絲不亂的頭發(fā)上踏拜,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機(jī)與錄音低剔,去河邊找鬼速梗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛襟齿,可吹牛的內(nèi)容都是我干的姻锁。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼猜欺,長吁一口氣:“原來是場噩夢啊……” “哼位隶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起开皿,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤涧黄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后赋荆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笋妥,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年糠睡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挽鞠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡狈孔,死狀恐怖信认,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情均抽,我是刑警寧澤嫁赏,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站油挥,受9級特大地震影響潦蝇,放射性物質(zhì)發(fā)生泄漏款熬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一攘乒、第九天 我趴在偏房一處隱蔽的房頂上張望贤牛。 院中可真熱鬧,春花似錦则酝、人聲如沸殉簸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽般卑。三九已至,卻和暖如春爽雄,著一層夾襖步出監(jiān)牢的瞬間蝠检,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工挚瘟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叹谁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓刽沾,卻偏偏與公主長得像本慕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子侧漓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容