软件开发者不免都要遇到压缩数据的问题经常使用Delphi的朋友都知道它为我们提供了两个流类TCompressionStream和TDecompressionStream来完成数据的压缩和解压缩但美中不足的是该流在Delphi的帮助中没有详细的说明使得它们在使用起来有一定得困难。其实在Delphi系统中提供了这两个类的源代码和库。保存在Delphi光盘的InfoExtraslib Src和InfoExtraslibObj目录中其中OBJ目录中保存的是库 Src目录中保存的是源代码感兴趣的朋友可以看看 。本人在使用的过程中对它们有了一定的了解。
一、 类的说明
1、 基类TCustomZlibStream类TCustomZlibStream是类TCompressionStream和
TDecompressionStream类的基类它主要有一个属性 OnProgress在类进行压缩或解压缩的过程中会发生这个的事件它的定义如下
Procedure OnProgress (Sender: TObject) ; dynamic;
2、 压缩类TCompressionStream类TCompressionStream除了继承了基类的OnProgress属性外又增加了一个属性 CompressionRate它的定义如下
Property CompressionRate: Single read GetCompressionRate;通过这个属性可以得到压缩比。
它的几个重要的方法定义如下
Constructor TCompressionStream.Create (CompressionLevel: TCompressionLevel; Dest:TStream) ;
其中 TcompressionLevel 压缩类型 它由如下几个定义
①、 clNone 不进行数据压缩
②、 clFastest进行快速压缩牺牲压缩效率
③、 clDefault进行正常压缩
④、 clMax 进行最大化压缩牺牲速度
Dest 目的流用于存放压缩过的数据。
Function TCompressionStream.Write (const Buffer; Count: Longint) : Longint;
其中 Buffer需要压缩的数据
Count:需要压缩的数据的字节数
函数返回写入流的字节数。
压缩类TCompressionStream的数据只能是写入的如果试图从其内部读取数据将发生一个"Error"异常。需要压缩的数据通过方法Wr i te写入流中在写入的过程中就被压缩并保存在由构造函数提供的内存流TmemoryStream中,同时触发OnProcess事件。
3、解压缩类TDecompressionStream:和压缩类TcompressionStream相反它的数据是只能读出的如果试图往其内部写数据将发生一个"Error "异常。它的几个重要方法定义如下
构造函数 Constructor Create(Source: TStream) ;
其中 Source是保存着压缩数据的流
Function Read(var Buffer; Count: Longint) : Longint;
数据读出函数 Buffer 存数据缓冲区
Count:缓冲区的大小
函数返回读出的字节数。
数据在读出的过程中数据被解压缩并触发OnProcess事件。
二、 类的使用
通过类TCompressionStream和TdecompressionStream的配合使用我们可以非常方便地完成数据的压缩和解压下面就是本人在编写屏幕拷贝程序中的使用例子
Procedure TClientForm.GetScreen;
Var
SourceDC,DestDC:HDC;
Bhandle:HBITMAP;
BitMap:TBitMap;
BmpStream,Deststream:TMemoryStream;
SourceStream:TCompressionStream;
Count:Integer;
Begin
SourceDC:=CreateDC('display' , ' ' , ' ' ,nil) ;
{得到屏幕的DC}
DestDC:=CreateCompatibleDC(SourceDC) ;
{建立临时DC}
Bhandle:=CreateCompatibleBitmap(SourceDC,Screen.Width, Screen.Height) ;
{建立位图}
SelectObject(DestDC,Bhandle) ;
{选择位图DC}
BitBlt(DestDC,0,0,Screen.Width, Screen.Height,SourceDC,0,0,SRCCOPY) ;
{拷贝整个屏幕}
BitMap:=TBitMap.Create;
BitMap.Handle := Bhandle;
{保存屏幕位图到BitMap中}
BmpStream:=TMemoryStream.Create;
BitMap.SaveToStream(BmpStream) ;
{建立位图数据的内存流}count:=BmpStream.Size;
{保存位图的大小}
DestStream:=TMemoryStream.Create;
{目标流保存压缩数据}
SourceStream:=TCompressionStream.Create(clMax, DestStream) ;
{构建压缩流采用最大化压缩并保存到目标流中}try
BmpStream.SaveToStream(SourceStream) ;
{压缩位图流}
SourceStream.Free;
{完成压缩释放压缩流}
BmpStream.Clear;
{清空原来位图流}
BmpStream.WriteBuffer(Count, Sizeof(Count) ) ;
{将原来位图的大小保存到新的位图流中 以便使用}
BmpStream.CopyFrom(DestStream, 0) ;
{将压缩数据附加到新的位图流后面}
BmpStream.Position := 0;
NMStrm.PostIt(BmpStream) ;
{发送位图流}finally
DestStream.Free;
BmpStream.Destroy ;
BitMap.Destroy;
DeleteDC(SourceDC) ;
ReleaseDC(Bhandle,SourceDC) ;end;
{释放有关资源}
End;
该过程得到整个屏幕的图象拷贝并利用压缩流SourceStream和内存流Deststream将位图压缩并重新把位图大小和压缩数据流保存到位图流中发送出去发送位图大小的目的是在解压前来确定需要的内存空间。
procedure TServerForm.NMStrmServMSG(Sender: TComponent;const sFrom: String; strm: TStream) ;
Var
StreamStr,DestStream:TMemoryStream;
SourceStream:TDecompressionStream;count:Integer;buffer:pointer;begin
ScreenImage.Picture.Bitmap:=nil;
If Strm Is TMemoryStream Then
StreamStr := Strm AS TMemoryStream
Else
Exit;
StreamStr.Position := 0;
StreamStr.ReadBuffer(Count, Sizeof(Count) ) ;
{得到位图的大小}
GetMem(Buffer,Count) ;
{申请数据空间}
DestStream := TMemoryStream.Create;
SourceStream := TDecompressionStream.Create(StreamStr) ;{构建解压流压缩数据由StreamStr流得到}
StatusBar.SimpleText := '正在处理图象' ;
Try
SourceStream.ReadBuffer(Buffer^,Count) ;
{读出解压数据}
DestStream.WriteBuffer(Buffer^,Count) ;
{保存到位图流中}
DestStream.Position := 0;
ScreenImage.Picture.Bitmap.LoadFromStream(DestStream) ;{显示到屏幕上}
Finally
FreeMem(Buffer) ;
DestStream.Destroy;
SourceStream.Destroy;
End;end;
该过程首先从得到的数据流中取得位图大小并申请内存空间然后建立解压流并将解压数据保存到位图流中然后显示到屏幕上。delphi压缩与解压 比较简单也比较实用对我来说已经足够我只想让客户端下载一个压缩文件到本地后解压出来就行看网上有用什么控件的我的是delphi6没装那控件在公司管的比较严要装控件比较麻烦。不扯了看代码吧。
[html] viewplain copy
1. unitunzip;
2.
3. interface
4.
5. uses
6. Windows,Messages,SysUti ls,Variants,Classes,Graphics,Controls,
Forms,
7. Dialogs,StdCtrls;
8.
9. ty p e
10. TForm1 =class(TForm)
11. Button 1:TButton;
12. Button2:TButton;
13. procedure Button1Cl ick(Sender:TObject);
14. procedure Button2Cl ick(Sender:TObject);
15. private
16. {Private declarations}
17. publ ic
18. {Publ icdeclarations}
19. end;
20.
21. va r
22. Form1:TForm1;
23.
24. implementation
25.
26. {$R*.dfm}
27.
28. usesZl ib;
29. //压缩函数
30. procedure Zip(var fs:TMemoryStream);
31. va r
32. cs:TCompressionStream;
33. ms:TMemoryStream;
34. num: Integer;
35. begin
36. if not(Assigned(fs)and(fs.Size>0)) then Exit;
37.
38. num:=fs.Size;
39. ms:=TMemoryStream.Create;
40. cs:=TCompressionStream.Create(clMax,ms);
41. try
42. fs.SaveToStream(cs);
43. cs.Free;
44. //ms.Position:=0;
45. fs.Clear;
46. fs.WriteBuffer(num, sizeof(num));
47. fs.CopyFrom(ms,0);
48. final ly
49. m s.Free;
50. end;
51. end;
52.
53. //解压函数
54. procedure UnZip2(var fs:Tmemorystream);
55. va r
56. ds:TDecompressionStream;
57. ms:TMemoryStream;
58. num: Integer;
59. begin
60. if not(Assigned(fs)and(fs.Size>0)) then Exit;
61.
62. fs.Position:=0;
63. fs.ReadBuffer(num,sizeof(num));
64. ms:=TMemoryStream.Create;
65. ds:=TDecompressionStream.Create(fs);
66. try
67. ms.SetSize(num);
68. ds.Read(ms.Memory^,num);
69. //ms.Position:=0;
70. fs.Clear;
71. fs.CopyFrom(ms,0);
72. final ly
73. d s.Free;
74. m s.Free;
75. end;
76. end;
77. //压缩测试
78. procedure TForm1.Button1Cl ick(Sender:TObject);
79. va r
80. ms:TMemoryStream;
81. begin
82. ms:=TMemoryStream.Create;
83. ms.LoadFromFi le('D:\delphi\szcb.mdb');
84. Zip(ms);
85. ms.SaveToFi le('D:\delphi\szcb.zip');
86. end;
87.
88. //解压测试
89. procedure TForm1.Button2Cl ick(Sender:TObject);
90. va r
91. ms:TMemoryStream;
92. begin
93. ms:=TMemoryStream.Create;
94. ms.LoadFromFi le('D:\delphi\szcb.zip');
95. UnZip2(ms);
96. ms.SaveToFi le('D:\delphi\szcb2.mdb');
97. end;
RepriseHosting是成立于2012年的国外主机商,提供独立服务器租用和VPS主机等产品,数据中心在美国西雅图和拉斯维加斯机房。商家提供的独立服务器以较低的价格为主,目前针对西雅图机房部分独立服务器提供的优惠仍然有效,除了价格折扣外,还免费升级内存和带宽,商家支持使用支付宝或者PayPal、信用卡等付款方式。配置一 $27.97/月CPU:Intel Xeon L5640内存:16GB(原...
Dynadot 是一家非常靠谱的域名注册商家,老唐也从来不会掩饰对其的喜爱,目前我个人大部分域名都在 Dynadot,还有一小部分在 NameCheap 和腾讯云。本文分享一下 Dynadot 最新域名优惠码,包括 .COM,.NET 等主流后缀的优惠码,以及一些新顶级后缀的优惠。对于域名优惠,NameCheap 的新后缀促销比较多,而 Dynadot 则是对于主流后缀的促销比较多,所以可以各取所...
昨天有分享到"2021年Vultr新用户福利注册账户赠送50美元"文章,居然还有网友曾经没有注册过他家的账户,薅过他们家的羊毛。通过一阵折腾居然能注册到账户,但是对于如何开通云服务器稍微有点不对劲,对于新人来说确实有点疑惑。因为Vultr采用的是预付费充值方式,会在每月的一号扣费,当然我们账户需要存留余额或者我们采用自动扣费支付模式。把笔记中以前的文章推送给网友查看,他居然告诉我界面不同,看的不对...