引 言
在日常中
我們一定使用過WINZIP
WINRAR這樣的出名的壓縮軟件
就是我們開發軟件過程中不免要遇到數據加密
數據壓縮的問題!本文中就這一技術問題展開探討
同時感謝各位網友的技巧
在我每次面對問題要解決的時候
是你們辛苦地摸索出來的技巧總是讓我豁然開朗
問題迎刃而解
本篇文章主要是運用DELPH的強大的流處理方面的技巧來實現的數據加密壓縮
並用於實際的軟件程序開發中
將我個人的心得
開發經驗寫出來與大家分享
系統功能
)
數據壓縮
使用DELPHI提供的兩個流類(TCompressionStream和TDecompressionStream)來完成數據的壓縮和解壓縮
)
數據加密壓縮
通過Delphi編程中
流
的應用實現數據加密
主要采用Tstream的兩個派生類Tfilestream
Tmemorystream 來完成的
其中數據壓縮部分采用
)的實現方法
)
雙擊壓縮文件自動關聯解壓
通過更改注冊表的實現擴展名與程序文件的關聯
主要采用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 TCompressionStream
Create (CompressionLevel: TCompressionLevel; Dest: TStream);
其中
TcompressionLevel(壓縮類型)
它由如下幾個定義
1)
clNone
不進行數據壓縮
2)
clFastest
進行快速壓縮
犧牲壓縮效率
3)
clDefault
進行正常壓縮
4)
clMax
進行最大化壓縮
犧牲速度
Dest
目的流
用於存放壓縮過的數據
Function TCompressionStream
Write (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 zjy
exe
)
編譯資源文件
在DELPHI的安裝目錄的\Bin下
使用BRCC
exe編譯資源文件
RC
當然
也可以將BRCC
單獨拷貝到程序文檔目錄使用
例如
Brcc
wnhoo_reg
Rc
)
資源文件引用
…
implementation
{$R *
dfm}
{$R wnhoo_reg
Res}
…
)
調用資源文件
(
)存取資源文件中的位圖(Bitmap)
Image
Picture
Bitmap
Handle :=LoadBitmap(hInstance
資源標識符
);
注
如果位圖沒有裝載成功
程序仍舊執行
但是Image將不再顯示圖片
你可以根據LoadBitmap函數的返回值判斷是否裝載成功
如果裝載成功返回值是非
如果裝載失敗返回值是
另外一個存取顯示位圖的方法如下
Image
Picture
Bitmap
LoadFromResourceName(hInstance
資源標識符
);
(
)存取資源文件中的光標
Screen
Cursors[]是一個光標數組
使用光標文件我們可以將定制的光標加入到這個屬性中
因為默認的光標在數組中索引值是
所以除非想取代默認光標
最好將定制的光標索引值設為
Screen
Cursors[
] :=LoadCursor(hInstance
資源標識符
);
Image
Cursor :=
;
(
)存取資源文件中的圖標
將圖標放在資源文件中
可以實現動態改變應用程序圖標
Application
Icon
Handle := LoadIcon(hInstance
資源標識符
);
(
)存取資源文件中的AVI
Animate
ResName :=
MyAvi
; //資源標識符號
Animate
Active :=True ;
(
)存取資源文件中的JPEG
把jpeg單元加入到uses單元中
var
Fjpg : TJpegImage ;
FStream :TResourceStream ;
begin
Fjpg :=TJpegImage
Create ;
From:http://tw.wingwit.com/Article/program/Delphi/201311/24700.html