引言
在日常中我们一定使用过WINZIPWINRAR这样的出名的压缩软件就是我们开发软件过程中不免要遇到数据加密数据压缩的问题!本文中就这一技术问题展开探讨同时感谢各位网友的技巧在我每次面对问题要解决的时候是你们辛苦地摸索出来的技巧总是让我豁然开朗问题迎刃而解本篇文章主要是运用DELPH的强大的流处理方面的技巧来实现的数据加密压缩并用于实际的软件程序开发中将我个人的心得开发经验写出来与大家分享
系统功能
)数据压缩
使用DELPHI提供的两个流类(TCompressionStream和TDecompressionStream)来完成数据的压缩和解压缩
)数据加密压缩
通过Delphi编程中流的应用实现数据加密主要采用Tstream的两个派生类TfilestreamTmemorystream 来完成的其中数据压缩部分采用)的实现方法
)双击压缩文件自动关联解压
通过更改注册表的实现扩展名与程序文件的关联主要采用Tregistry并且API函数SHChangeNotify实现注册效果的立即呈现
)可生成自解压文件
自解压的文件实现数据压缩)与数据加密压缩)的自动解压并且通过资源文件的使用实现可执行的自解压文件与数据文件的合并来完成数据的自解压实现
系统实现
工作原理
[[The No Picture]]
关键技术的讲述
(一)ZLIB
)基类 TCustomZlibStream是类TCompressionStream和TDecompressionStream 类的基类它主要有一个属性 OnProgress在类进行压缩或解压缩的过程中会发生这个的事件
格式Procedure OnProgress (Sender: TObject); dynamic;
)压缩类TCompressionStream除了继承了基类的OnProgress 属性外又增加了一个属性CompressionRate它的定义如下
Property CompressionRate: Single read GetCompressionRate;
通过这个属性可以得到压缩比
它的几个重要的方法定义如下
Constructor TCompressionStreamCreate (CompressionLevel: TCompressionLevel; Dest: TStream);
其中TcompressionLevel(压缩类型)它由如下几个定义
1) clNone 不进行数据压缩
2) clFastest进行快速压缩牺牲压缩效率
3) clDefault进行正常压缩
4) clMax 进行最大化压缩牺牲速度
Dest目的流用于存放压缩过的数据
Function TCompressionStreamWrite (const Buffer; Count: Longint): Longint;
其中Buffer需要压缩的数据
Count: 需要压缩的数据的字节数
函数返回写入流的字节数
注意压缩类TCompressionStream的数据只能是写入的如果试图从其内部读取数据将发生一个Error 异常需要压缩的数据通过方法 Write写入流中在写入的过程中就被压缩并保存在由构造函数提供的内存流(TmemoryStream)中同时触发 OnProcess 事件
) 解压缩类 TDecompressionStream :和压缩类TcompressionStream相反它的数据是只能读出的如果试图往其内部写数据将发生一个Error 异常
它的几个重要方法定义如下
构造函数Constructor Create(Source: TStream);
其中Source 是保存着压缩数据的流
Function Read(var Buffer; Count: Longint): Longint;
数据读出函数Buffer 存数据缓沖区Count: 缓沖区的大小
函数返回读出的字节数数据在读出的过程中数据被解压缩并触发 OnProcess 事件
(二)流
在Delphi中所有流对象的基类为TStream类其中定义了所有流的共同属性和方法
TStream类中定义的属性如下
)Size:此属性以字节返回流中数据大小
)Position:此属性控制流中存取指针的位置
Tstream中定义的虚方法有四个
)Read:此方法实现将数据从流中读出返回值为实际读出的字节数它可以小于或等于指定的值
)Write:此方法实现将数据写入流中返回值为实际写入流中的字节数
)Seek:此方法实现流中读取指针的移动返回值为移动后指针的位置
函数原形为Function Seek(Offset:Longint;Origint:Word):Longint;virtual;abstract;
参数Offset为偏移字节数参数Origint指出Offset的实际意义其可能的取值如下
soFromBeginning:Offset为指针距离数据开始的位置此时Offset必须大于或者等于零
soFromCurrent:Offset为移动后指针与当前指针的相对位置
soFromEnd:Offset为移动后指针距离数据结束的位置此时Offset必须小于或者等于零
)Setsize:此方法实现改变数据的大小
另外TStream类中还定义了几个静态方法
)ReadBuffer:此方法的作用是从流中当前位置读取数据跟上面的Read相同
注意当读取的数据字节数与需要读取的字节数不相同时将产生EReadError异常
)WriteBuffer:此方法的作用是在当前位置向流写入数据跟上面的Write相同
注意当写入的数据字节数与需要写入的字节数不相同时将产生EWriteError异常
)CopyFrom:此方法的作用是从其它流中拷贝数据流
函数原形为Function CopyFrom(Source:TStream;Count:Longint):Longint;
参数Source为提供数据的流Count为拷贝的数据字节数当Count大于时CopyFrom从Source参数的当前位置拷贝Count个字节的数据当Count等于时CopyFrom设置Source参数的Position属性为然后拷贝Source的所有数据
Tstream常见派生类
TFileStream (文件流的存取)
TStringStream (处理内存中的字符串类型数据)
TmemoryStream (对于工作的内存区域数据处理)
TBlobStream (BLOB类型字段的数据处理)
TwinSocketStream(socket的读写处理)
ToleStream(COM接口的数据处理)
TresourceStream (资源文件流的处理)
其中最常用的是TFileStream类使用TFileStream类来存取文件首先要建立一个实例声明如下
constructor Create(const Filename:string;Mode:Word);
Filename为文件名(包括路径)
Mode为打开文件的方式它包括文件的打开模式和共享模式其可能的取值和意义如下
打开模式
fmCreate :用指定的文件名建立文件如果文件已经存在则打开它
fmOpenRead :以只读方式打开指定文件
fmOpenWrite :以只写方式打开指定文件
fmOpenReadWrite:以写写方式打开指定文件
共享模式
fmShareCompat :共享模式与FCBs兼容
fmShareExclusive:不允许别的程序以任何方式打开该文件
fmShareDenyWrite:不允许别的程序以写方式打开该文件
fmShareDenyRead :不允许别的程序以读方式打开该文件
fmShareDenyNone :别的程序可以以任何方式打开该文件
(三)资源文件
)创建资源文件
首先创建一个Rc的纯文本文件
格式 资源标识符关键字资源文件名
资源标识符程序中调用资源时的特殊标号
关键字标识资源文件类型
Wave 资源文件是声音文件
RCDATA JPEG文件
AVI AVI动画
ICON 图标文件
BITMAP 位图文件
CURSOR 光标文件
EXEFILE EXE文件
资源文件名资源文件的在磁盘上存储的文件全名
例如
myzjy exefile zjyexe
)编译资源文件
在DELPHI的安装目录的\Bin下使用BRCCexe编译资源文件RC当然也可以将BRCC单独拷贝到程序文档目录使用
例如
Brcc wnhoo_regRc
)资源文件引用
…
implementation
{$R *dfm}
{$R wnhoo_regRes}
…
)调用资源文件
()存取资源文件中的位图(Bitmap)
ImagePictureBitmapHandle :=LoadBitmap(hInstance资源标识符);
注如果位图没有装载成功程序仍旧执行但是Image将不再显示图片你可以根据LoadBitmap函数的返回值判断是否装载成功如果装载成功返回值是非如果装载失败返回值是
另外一个存取显示位图的方法如下
ImagePictureBitmapLoadFromResourceName(hInstance资源标识符);
()存取资源文件中的光标
ScreenCursors[]是一个光标数组使用光标文件我们可以将定制的光标加入到这个属性中因为默认的光标在数组中索引值是所以除非想取代默认光标最好将定制的光标索引值设为
ScreenCursors[] :=LoadCursor(hInstance资源标识符);
ImageCursor :=;
()存取资源文件中的图标
将图标放在资源文件中可以实现动态改变应用程序图标
ApplicationIconHandle := LoadIcon(hInstance资源标识符);
()存取资源文件中的AVI
AnimateResName :=MyAvi ; //资源标识符号
AnimateActive :=True ;
()存取资源文件中的JPEG
把jpeg单元加入到uses单元中
var
Fjpg : TJpegImage ;
FStream :TResourceStream ;
begin
Fjpg :=TJpegImageCreate ;