求delphi 的 gzip 算法,来者有分!

解决方案 »

  1.   

    但对Delphi程序员来讲,另有一个异常强大的压缩控件包不可以不用,那就是Microchip Data System推出的TZipTV压缩控件包,该控件包由Carl Bunton编写,目前最高版本为1.61,属于共享软件。之所以说它异常强大,有以下几个原因:(1)支持的压缩编码格式多达17种,包括 ZIP、ZOO、RAR、ARJ、ARC、CAB、HA、LHA、LZH、PAK、TAR、GZIP、Z、BH、UUE、XXE和ENC。(2)除了处理CAB和RAR压缩文件需要Cabnet.dll和Unrar.dll外,处理其它格式都不依赖额外的DLL,也就是可以把绝大部分代码都编译在你的软件中。(非常符合目前的“绿色软件“标准吧!)(3)TZipTV控件包的设计非常全面周到,使程序员拥有充分的控制权,可以在需要的位置加入自己的处理代码。(4)除了为数不多的限制外,共享版和注册版在功能上几乎一样,并且没有时间限制,但非注册版控件编译后,软件运行出现的第一个窗口总是TZipTV的一个声明(显示这是一个非注册版,但不影响程序以后的运行)。看了以上的介绍,您肯定想知道如何使用这个控件包,下面我就来做一个简单的说明。
      TZipTV控件包包括二类控件:(1)压缩和解压缩控件,它又分为三类。1. 压缩控件4个:TBlackHole、 TZip、TLha和TMakeCab。2. 解压缩控件11个:TUnBH (BlakHole)、TUnARC、TUnARJ、TUnCAB、TUnGZIP、TUnLHA、TUnRAR、TUnTAR、TUnZIP和TUnZOO。以上各种控件的作用从它们的名称上就可以看出,勿需多加解释。3.其它控件6个:TArc2Arc(用来对文件的压缩格式进行转换)、TZipTV(显示压缩文件中的文件信息)、TZipCheck(校验压缩文件的完整性)、TUnSFX(将自解压文件转换成正常的压缩格式)、TZipSearch(在压缩文件中直接查找内容)和TTurboSearch(可同时对多个压缩文件进行查找)。(2)E-mail附件文件的编码和解码控件:TUUEncode和TUUDecode(本文对这两个控件不做介绍)。
      使用以上各个控件和使用Delphi的标准控件一样,把所需要的控件放在窗体上,对控件的主要属性进行赋值,在相应的事件中加入您的处理代码,然后调用该控件的方法,具体内容您可以参考TZipTV控件包的帮助文件,典型的使用代码如下:
      ZipTV1.ArchiveFile :=` C:\Myzip.zip';
      {指明要处理哪个压缩文件,包含路径和文件名}
      ZipTV1.FileSpec :=`*.* ';
       {指明要处理压缩文件中哪种类型文件或将哪种类型文件加入到压缩文件中,允许使用通用符,为TStringList变量} 
      ZipTV1.Activate; {解压缩控件的调用声明为:UnZIP1.Extract}
      然后在需要的事件中加入您准备的处理代码,主要事件激发顺序如下:OnActivate →OnRead →OnTotals →OnDeactivate。
      有关事件的功能说明:
      OnActivate:调用Activate或Extract方法后立即激活,控件开始工作时激活。
      OnRead :每处理压缩文件中一个文件即激活一次,以下是与处理每一个文件相关的事件:
      OnBegin:处理一个文件前激活。
      OnEnd: 处理一个文件结束后激活。
      OnTotals: 处理完压缩文件中的全部文件后激活。
      OnDeactivate:控件完成工作后激活。
      OnError:控件处理遇到错误时激活,如无代码,则自动忽略错误。
      OnNextVolume:处理多卷压缩文件时激活。
      OnGetPassword:处理口令加密的压缩文件时激活,以便用户输入口令。
      OnProgresss:控件工作过程中,按照ProgresssNotify属性中定义的进度比例定时激活,用来显示工作进度。
      OnFileExists:限于TArc2Arc控件和全部解压缩控件。在生成新的目标文件时,若同名文件已经存在则激活,用以防止错误覆盖文件。
      看了以上各种事件,您是不是感到对程序的运行有了充足的控制权,当然,并不是每个控件都拥有以上全部的事件,也还有几个次要事件我在此未予列出,具体编程时您可以参照相应控件的帮助说明。此外,需加说明的是,不同控件的同名事件可以使用同一个事件处理程序,如你已经在Unzip1.OnRead事件中书写了一段处理程序,在UnRar1.OnRead中则勿需另写同样代码,只需在Delphi中的Object Inspector中将UnZip1.OnRead赋予UnRar1.OnRead即可。
      从前文介绍可以看出压缩/解压缩控件分为三类:压缩控件、解压缩控件和提取压缩文件信息的控件,因此TZipTV控件包预定义了相应的三个基本对象:TCompBase、 TUnBase和TZipCommon。其中TZipCommon是所有TZipTV控件的父对象。在编程中,必须运用这三个对象来进行协调各种控件。由于TZipTV控件包的帮助文件中未对这三种基类作任何解释,所以在此举例加以说明:
      1.读出压缩文件内的文件信息,并显示在一个ListView中。
      PROCEDURE TForm1.ZipTV1Read(Sender: TObject; Offset, Filenum: INTEGER); {为OnRead事件代码}
      VAR
       NewItem : TListItem; {ListView的子项}
       ZipCommon: TZipCommon; {TZipCommon基类的变量}
      BEGIN
       ZipCommon := TZipCommon( Sender ); {创建一个TZipCommon基类实例}
       NewItem := ListView1.Items.Add; {ListView中新增加一个子项}
       WITH NewItem DO {为每一个新子项增加实际内容}
       BEGIN
       ImageIndex := ZipCommon.ImageIndex; {显示文件类型的系统图标}
       Caption := ZipCommon.Filename ; {显示文件名}
       WITH SubItems DO {增加子结点内容}
       BEGIN
       Add( FormatDateTime( `mm' + DateSeparator +`dd' + DateSeparator + `yy hh:mm', ZipCommon.Date ) ); {显示文件日期} 
       Add( IntToStr( ZipCommon.PackedSize ) ); {显示文件压缩后的大小}
       Add( IntToStr( ZipCommon.UnpackedSize ) ); {显示文件压缩前的大小}
       Add( IntToStr( ZipCommon.Ratio ) + `%' ); {显示文件压缩比例}
       Add( ZipCommon.sCompressionMethod ); {显示文件压缩模式} 
       Add( ZipCommon.GetFileType( ZipCommon.Filename ) ); {显示文件类型说明}
       IF ZipCommon.Encrypted THEN Add(`Yes' ) ELSE Add(`No' ); {显示文件是否被加密} 
       Add( ZipCommon.VolumeName ); {显示文件所属卷名} 
       Add( StrPas( ZipTV1.FileComment ) ); {显示文件说明} 
       END;
       END;
      END;
      2.压缩控件的调用方法:
      已定义变量: 
       CompressComponent:TCompBase;
      以下处理不同压缩格式文件的代码:
       CompressComponent := NIL;
       WITH ZipTV1 DO {已将要处理的压缩文件如上用TZipTV控件打开}
       IF NOT IsArcCompressable( ArcType ) THEN 
       ShowMessage(`不支持对该文件的压缩' )
       ELSE
       CASE ArcType OF {ArcType属性等于压缩文件的格式}
       atBH : CompressComponent := BlakHole1;
       atCAB : CompressComponent := MakeCab1;
       atZip,
       atZip250 : CompressComponent := Zip1;
       atLha,
       atLzh : CompressComponent := Lha1;
       END;
      以下为具体压缩操作的代码:
       CompressComponent.FileSpec.clear;
       CompressComponent.FileSpec.Add(`<要进行处理的文件名> ' );
       CompressComponent.Switch := swDelete; {TSwitch 取值包括swAdd、swMove、swDelete和swRead ,分别表示对文件进行添加、移动、删除和读取}
       IF CompressComponent.FileSpec.Count > 0 THEN CompressComponent.Activate;
      3.解压缩控件的调用方法,与上2类似:
      已定义变量: 
       ExtractComponent :TUnBase;
      程序典型代码:
       CASE ZipTV1.ArcType OF
       atArc, atArcExe : ExtractComponent := UnARC1;
       atArj, atArjExe : ExtractComponent := UnARJ1;
       atBH, atBHExe : ExtractComponent := UnBH1;
       atCAB : ExtractComponent := UnCAB1;
       atGZIP : ExtractComponent := UnGZIP1;
       atLHA, atLhaExe, atLZH, atLzhExe : ExtractComponent := UnLHA1;
       atTar : ExtractComponent := UnTAR1;
       atUUE : ExtractComponent := UUDecode1;
       atRAR : ExtractComponent := UnRAR1;
       atZip, atZipExe, atZip250, atZip250Exe :
       BEGIN
       ExtractComponent := UnZIP1;
       ExtractComponent.ZipCmntBufSize := ZipTV1.ZipCmntBufSize;
       END;
       atZoo : ExtractComponent := UnZOO1;
       ELSE
       BEGIN
       MessageDlg(`不支持该类型文件的解压缩', mtInformation, [mbOK], 0 );
       EXIT;
       END;
       END;
      ExtractComponent.ArchiveFile := ZipTV1.ArchiveFile;
      ExtractComponent.Extract;
      在此需要说明的是TUnBase类型控件解压缩除了调用Extract方法外,还可以根据具体要求调用ExtractToMemoryStream 、ExtractToFileStream和ExtractToPointer 方法来实现对文件的解压缩,增加了使用上的弹性。
      举了以上例子,并不意味着一定要使用这三个基类来进行操作,可以直接应用它们的相应子类控件。但如果需要同时处理多种压缩格式,则需要利用以上基类,实现自动转换,从而用同样的代码来处理不同的压缩格式。
      文章到此就基本结束了,不知您对TZipTV控件包是否有了一个大体认识。如果你觉得有使用价值的话,赶快到http://www.ziptv.com去下载一个吧。最后额外说一句,注册版多出的功能是可以制作自解压文件和支持文件的口令加密。