zlib2

ZIP文件是一種很常見的壓縮文件格式,用戶在windows下經常要使用WINZIP程序進行文件壓縮和解壓操作。不過,WINZIP程序只能由用戶操作,而沒有提供開發方面的接口。這樣,要想在用戶的應用程序中加入文件壓縮和解壓功能,就有一定困難了。幸好,有ZLIB這個開放源代碼的壓縮和解壓庫可供開發人員使用。不過,ZLIB雖然支持文件壓縮和解壓,但只能對Linux/Unix下的GZ文件進行讀寫操作,對於Windows系統下的ZIP文件並不提供直接的支持。要解決ZLIB不能直接操作Windows ZIP文件的矛盾,就需要對WindowsZIP文件結構進行分析,再結合ZLIB所提供的相關函數,加上一些開發技巧,自行開發相應的Winzip程序。

一、ZIP文件結構
ZIP文件基本結構如下:

{分文件頭信息+文件壓縮數據}+中心目錄+中心目錄記錄結束符



更詳細的說明如下:

    每個分文件頭信息後面緊跟此文件壓縮數據。如果壓縮方式是不壓縮,就是該文件的從第1個字節一直到最後一個字節的原始字節流;如果壓縮方式是deflate,壓縮數據就是經過deflate算法壓縮過的字節流。

ZIP文件中通常有若干個分文件數據,最多可達到65535個。

文件的最後修改時間和日期按MS-DOS時間日期格式編碼。時間和日期均爲16位整數。

對於時間,16位格式分配如下:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

小時

對於日期,16位格式分配如下:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

-1980

ZIP文件使用32CRC校驗碼檢查數據是否有誤。

    ZIP文件中單個文件和ZIP文件本身字節數不能大於4G,否則會出錯。

文件名實際長度由文件名長這個字段指定,文件名中可以包含路徑,但不包含驅動器盤符(要特別注意的是,所有路徑分割符’\’都要轉換爲’/’,並且路徑中第一個字符不能是’/’)。

外部文件屬性這個字段,最低1個字節是文件的DOS屬性字節,其它字節均設爲0)。其中DOS屬性字節格式如下:

7

6

5

4

3

2

1

0

未用

未用

檔案

目錄

卷標

系統

隱藏

只讀

分文件頭相對位移和中心目錄初始偏移都是按字節表示的相對於ZIP文件開始位置的偏移量,用於在ZIP文件中準確定位。

中心目錄中每個文件都可以有註釋,用戶可以將需要保存的額外信息保存在該字段中。

二、ZLIB使用說明

ZLIB的作者是文件壓縮方面的專家,通過一系列複雜的算法實現了deflate這種格式的壓縮與解壓,並且爲開發人員提供了相對簡單的函數接口。

ZLIB流格式在RFC1950中有詳細的定義。對於ZLIB流,除去流中開頭的2個字節和結尾的4個字節,中間的連續字節流即經過deflate轉換的壓縮流。

ZLIB是開放源代碼的,可以從www.zlib.net上下載源代碼包,也可以下載編譯好的Windows系統下的DLL。目前最新的ZLIB版本爲1.2.3dll文件名爲zlib1.dll,頭文件名爲zlib.h,還需要用一個zconf.h

本程序一共使用了ZLIB提供的6個函數,其中壓縮函數3個,解壓函數3個。

壓縮要用到deflateInitdeflatedeflateEnd3個函數,解壓要用到inflateInitinflateinflateEnd3個函數。

deflateInit在壓縮開始之間調用,壓縮結束後調用deflateEnd;同樣,解壓之前調用inflateInit,解壓完成後調用inflateEnd。這4個函數都很好理解。

關鍵函數是deflate進行壓縮,inflate進行解壓。

deflate函數有兩個參數,streamflushstream是一個結構體變量,有next_inavail_innext_outavail_out這四個變量。next_in表示當前輸入的字節數組,avail_in表示當前可用的輸入字節數;next_out表示當前輸出的字節數組,avail_out表示當前可用的輸出字節數。當輸入數據沒有結束時flush設爲Z_NO_FLUSH,否則設爲Z_FINISHnext_out要至少比next_in0.0015%

inflate函數參數和deflate相同,但flush總是設爲Z_NO_FLUSH

爲壓縮整個文件,應當循環調用deflate函數進行數據壓縮。同樣,也要循環調用inflate函數進行解壓。當avail_out這個變量爲0時,表示輸出緩衝已滿,這時需要將next_out中數據寫入文件,寫入字節數由next_out大小-avail_out決定。然後重新調用deflate進行壓縮或inflate進行解壓。

三、程序開發過程

本程序使用Visual C++ 6.0開發。使用MFC AppWizard生成基於對話框的應用程序框架。

主對話框截圖如圖1所示。


1  主界面

主對話框中加入菜單,包括文件和動作兩個子菜單,其中文件菜單中只有一個打開菜單項,用於打開ZIP文件。動作菜單有加入、刪除、解出三個菜單項。

菜單下面是一個MSFlexGrid控件,用於顯示ZIP文件中的文件。

主對話框底部有三個標籤,用於顯示有關信息。

用戶單擊文件菜單的打開命令,會出現打開文件對話框,用於打開或新建ZIP文件。

用戶單擊動作菜單中的加入命令,會出現選擇文件對話框,由用戶選擇要加入的文件。

選擇文件對話框截圖如2所示。



2選擇文件對話框

該對話框中,壓縮和保存路徑兩個複選按鈕默認都是選中狀態,即進行壓縮和保存文件路徑,用戶可以改變這個設置。壓縮複選按鈕左邊是一個下拉列表框,由用戶選擇驅動器,上面的MSFlexGrid列表用於顯示當前目錄和文件,用戶在該列表按空格鍵選擇文件,選中文件將出現在對話框下面的列表框中,單擊確定按鈕則進行將選擇文件加入ZIP文件。

用戶單擊動作菜單的解壓按鈕,會出現解壓對話框,由用戶輸入解壓路徑。

解出對話框截圖如下:

用戶只要輸入一個解壓目錄,並單擊確定按鈕,就會將ZIP文件中文件解壓至該目錄。

源文件中,有4個包含開發時加入的源代碼:winzip.cpp中定義一些全局變量;selectfiledlg.cpp爲選擇文件對話框類;extractdlg.cpp爲輸入解壓路徑對話框類;winzipdlg.cpp爲主對話框類,其中包含主要的源代碼;其它文件均由MFC自動生成。2
發佈了16 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章