还有读入已经压缩的文件进行解压缩?可否不用生成临时文件(就是未压缩的实际文件)?
解决方案 »
- delphi执行外部程序等待程序运行成功,而不是程序退出
- 请教DELPHI高手
- 终于发现为什么D版越来越冷清了...
- bde配置不知道怎么回事,老是配置不好,谁能帮我?有酬劳!
- 用Delphi开发的Com组件,在关闭或重启计算机是(未关闭组件),提示DllHost错误(数据可能丢失)?
- 求谁有计算机方面的奇闻逸事
- 如何对一个应用程序进行时间和次数进行限制,急!!!!
- 如何显示数据库里的JPG图片文件
- 怎么能分辨出单双数,然后显示在label上呢?
- 怎么做出如FoxMail在Win2000下的半透明窗口?
- 在win2000下可用,在98下就报错了,ADO+ACCESS
- isapi 的dll在98 下可以操作注册表,为何在win2000下就不行呢?
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去下载一个吧。最后额外说一句,注册版多出的功能是可以制作自解压文件和支持文件的口令加密。
广西南宁超创信息工程有限公司 蔡健
Borland公司推出的 RAD开发工具 Delphi 5.0作为 Windows平台上的主流开发工具,其可视化的开发环境和面向对象编程的强大功能已经吸引了无数的开发人员。但是,一些程序员在实际的开发过程中却时常为对大量的数据进行压缩而伤透脑筋,不得不去查找一些高效的压缩算法或在网上查找第三方的控件来实现压缩。难道 Delphi本身没有提供这个功能吗?其实 Delphi的程序设计师早就考虑到了这一点,他们提供了 Zlib.pas和 Zlibconst.pas两个单元文件来解决数据压缩问题,实现了很高的数据压缩比率。这两个文件保存在 Delphi 5.0安装光盘上 \Info\Extras\Zlib目录下,此外,在 Info\Extras\Zlib\Obj目录中还保存了 Zlib.pas单元引用的 Obj文件。下面本文以压缩一个屏幕拷贝为例介绍如何使用这项功能。
解决思路
首先利用屏幕拷贝捕捉到当前整个屏幕的图像,然后在内存中保存为 BMP文件格式。压缩时,使用 TCompressionStream对象对原始图像进行压缩并且保存为自定义的文件格式;解压缩时,使用 TDecompressionStream对象对被压缩的图像进行解压缩,还原为 BMP格式的图像文件。
具体实现
新建一个项目文件,在主单元的接口部分引用 Zlib.pas,在主表单上放置两个按钮 Button1、 Button2,在它们的 OnClick事件中写上相应的过程调用代码。
部分程序源代码如下:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls, Zlib;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$ R* .DFM}
1.捕捉全屏幕图像
procedure GetScreen(var Bmp: TBitmap);
var
Dc: HDC;
MyCanvas: TCanvas;
MyRect: TRect;
begin
Dc := GetWindowDC(0);
MyCanvas := TCanvas.Create;
try
MyCanvas.Handle := Dc;
MyRect:=Rect(0, 0,Screen.Width, Screen.Height);
//图像为 24位真彩色,也可根据实际需要调整
Bmp.PixelFormat := pf24bit;
Bmp.Width := MyRect.Right;
Bmp.Height := MyRect.Bottom;
//捕捉整个屏幕图像
Bmp.Canvas.CopyRect(MyRect, MyCanvas, MyRect);
finally
MyCanvas.Handle := 0;
MyCanvas.Free;
ReleaseDC(0, Dc);
end;
end;
2.压缩图像
procedure CompressBitmap(var CompressedStream: TMemoryStream;const CompressionLevel: TCompressionLevel);
var
SourceStream: TCompressionStream;
DestStream: TMemoryStream;
Count: Integer;
Begin
//获得图像流的原始尺寸
Count := CompressedStream.Size;
DestStream := TMemoryStream.Create;
SourceStream:=TCompressionStream.Create
(CompressionLevel, DestStream);
Try
//SourceStream中保存着原始的图像流
CompressedStream.SaveToStream(SourceStream);
//将原始图像流进行压缩, DestStream中保存着压缩后的图像流
SourceStream.Free;
CompressedStream.Clear;
//写入原始图像的尺寸
CompressedStream.WriteBuffer(Count, SizeOf
(Count));
//写入经过压缩的图像流
CompressedStream.CopyFrom(DestStream, 0);
finally
DestStream.Free;
end;
end;
3.还原被压缩图像
procedure UnCompressBitmap(const CompressedStream: TFileStream; var Bmp: TBitmap);
var
SourceStream: TDecompressionStream;
DestStream: TMemoryStream;
Buffer: PChar;
Count: Integer;
Begin
//从被压缩的图像流中读出原始图像的尺寸
CompressedStream.ReadBuffer(Count, SizeOf(Count));
//根据图像尺寸大小为将要读入的原始图像流分配内存块
GetMem(Buffer, Count);
DestStream := TMemoryStream.Create;
SourceStream := TDecompressionStream.Create(CompressedStream);
Try
//将被压缩的图像流解压缩,然后存入 Buffer内存块中
SourceStream.ReadBuffer(Buffer^, Count);
//将原始图像流保存至 DestStream流中
DestStream.WriteBuffer(Buffer^, Count);
DestStream.Position := 0;//复位流指针
//从 DestStream流中载入原始图像流
Bmp.LoadFromStream(DestStream);
finally
FreeMem(Buffer);
DestStream.Free;
end;
end;
4.压缩按钮 OnClick事件
procedure TForm1.Button1Click(Sender: TObject);
var
Bmp: TBitmap;
CompressedStream: TMemoryStream;
begin
Bmp := TBitmap.Create;
CompressedStream := TMemoryStream.Create;
Try
//捕获当前整个屏幕 ,将图像保存至 Bmp对象中 GetScreen(Bmp);
//将 Bmp对象中的图像保存至内存流中
Bmp.SaveToStream(CompressedStream);
//按缺省的压缩比例对原始图像流进行压缩
CompressBitmap(CompressedStream, clDefault);
//将压缩之后的图像流保存为自定义格式的文件
CompressedStream.SaveToFile(‘ C:\cj.dat’ );
finally
Bmp.Free;
CompressedStream.Free;
end;
end;
5.解压缩按钮 OnClick事件
procedure TForm1.Button2Click(Sender: TObject);
var
CompressedStream: TFileStream;
Bmp: TBitmap;
begin
Bmp := TBitmap.Create;
//以文件流的只读方式打开自定义的压缩格式文件
CompressedStream := TFileStream.Create(‘ C:\cj.dat’ , fmOpenRead);
Try
//将被压缩的图像流进行解压缩
UnCompressBitmap(CompressedStream, Bmp);
//将原始图像流还原为指定的 BMP文件
Bmp.SaveToFile(‘ C:\cj.bmp’ );
finally
Bmp.Free;
CompressedStream.Free;
end;
end;
此外 TCompressionStream对象还提供了 CompressionRate属性,该属性用于描述对原始数据进行压缩后的压缩比率,而 OnProgress事件在压缩与解压缩过程中都会被触发,开发人员可以在该事件中编写用于显示进度的代码。
以上代码在 Delphi 5.0中调试运行通过。