zlib2

来源:互联网 发布:有淘宝优惠券的网站 编辑:程序博客网 时间:2024/05/17 06:03

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
原创粉丝点击