使用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 中文測(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:

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

  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è)文件。對(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é)束。

參考資料

Minizip

轉(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)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容