TResourceStream對象
TResourceStream對象是另一類MemoryStream對象它提供對Windows 應用程序資源的訪問因此稱它為資源流TResourceSream也是從TCustomMemoryStream 繼承的因此在TCustomMemoryStream對象的基礎上定義了與指定資源模塊或資源文件建立連接的構造方法並且還覆蓋了Write以實現向資源文件中寫數據
下面介紹TResourceStream的實現
私有域
TResourceStream沒有定義新的屬性但它在private部分定義了兩個數據域HResInfo和HGlobol和一個私有方法Initialize它們的定義如下
TResourceStream = class(TCustomMemoryStream)
private
HResInfo: HRSRC;
HGlobal: THandle;
procedure Initialize(Instance: THandle; Name ResType: PChar)
…
end;
HRSRC是描述Windows資源信息的結構句柄HGlobal變量代表資源所在模塊的句柄如果操作的是應用程序資源HGlohal就代表EXE程序的句柄如果是動態鏈接庫(DLL)則HGlobal 代表動態鏈接庫的句柄TResourceStream對象使用這兩上變量訪問應用程序或動態鏈接庫中的資源
Initialize方法是TResourceStream對象內部使用的它的構造方法Create和CreateFromID都是調用Initialize方法完成對TResourceStream的初始化它的實現如下
procedure TResourceStreamInitialize(Instance: THandle; Name ResType: PChar)
procedure Error;
begin
raise EResNotFoundCreate(FmtLoadStr(SResNotFound [Name]))
end;
begin
HResInfo := FindResource(Instance Name ResType)
if HResInfo = then Error;
HGlobal := LoadResource(Instance HResInfo)
if HGlobal = then Error;
SetPointer(LockResource(HGlobal) SizeOfResource(Instance HResInfo))
end;
該方法實現中首先調用Windows函數FoundResource得到由參數Instance指定的模塊中的名為Name和類型為ResType的資源然後調用LoadResource將資源調用內存並返回該資源在內存中的句柄最後將該資源復制到ResourceStream中方法的Instance參數代表要調用的資源所在的模塊句柄模塊可以是可執行文件也可以是動態鏈接庫如果在讀取資源時沒在模塊中發現要找的資源則產生異常事件
構造方法Create和CreateFromID
這兩個方法在實現上沒有大的不同顧名思義第一個方法是通過資源名構造TResourceStream; 第二個方法通過資源ID構造TResourceStream而且在實現過程中它們都調用了Initialize方法下面是它們的實現
constructor TResourceStreamCreate(Instance: THandle; const ResName: string;
ResType: PChar)
begin
inherited Create;
Initialize(Instance PChar(ResName) ResType)
end;
constructor TResourceStreamCreateFromID(Instance: THandle; ResID: Integer;
ResType: PChar)
begin
inherited Create;
Initialize(Instance PChar(ResID) ResType)
end;
這兩個方法中都有Instance參數該參數值的含義在Insitialize中介紹過
Write方法
TResourceStream的Write方法只完成一件事就產生這個異常事件其實現如下
function TResourceStreamWrite(const Buffer; Count: Longint) Longint;
begin
raise EStreamErrorCreateRes(SCantWriteResourceStreamError)
end;
從方法實現中可以看到TSourceStream對象是不允許寫數據的一旦往資源流中寫數據將產生異常事件
析構方法Destroy
該方法產生給資源解鎖然後釋放該資源最後調用繼承的Destroy方法釋放ResourceStream其實現如下
destructor TResourceStreamDestroy;
begin
UnlockResource(HGlobal)
FreeResource(HResInfo)
inherited Destroy;
end;
回顧Initialize方法我們不難發現
● ResourceStream沒有額外地給資源重新分配內存而是直接使用HGlobal句柄所指 的內存域
● ResourceStream中的資源在流的生存期始終是Lock狀態因此要根據Windows 的內存使用規則合理安排ResourceStream的使用
● ResourceStream只是用於訪問應用程序和動態鏈接庫中的資源的
在Classes在單元中提供了InternalReadComponentRes函數該函數使用了TResourceStream對象從Delphi應用程序中讀取部件Delphi是將窗體和部件信息放在模塊資源的RCDATA段的
TBlobStream對象
從Delphi 數據庫開發平台這個意義上說TBlobStream 對象是個很重要的對象TBlobStream對象提供了修改TBlobFieldTBytesField或TVarBytesField中數據的技術開發者可以象對待文件或流那樣在數據庫域中讀寫數據
傳統數據庫發展的一個重要趨向是往多媒體數據庫發展目前比較著名和流行的數據庫都支持多媒體功能多媒體數據存儲中的一大難點是數據結構不規則數據量大各大數據庫產品是采用BLOB技術解決多媒體數據存儲中的問題Delphi的TBlobStream對象的意義就在於一方面可以使Delphi應用程序充分利用多媒體數據庫的數據管理能力另一方面又能利用Object Pascal的強大程序設計能力給多媒體數據庫提供全方向的功能擴展余地
使用TBlobStream對象可以在多媒體數據庫的BLOB字段存儲任意格式的數據一般說來許多多媒體數據庫只能支持圖像語音或者OLE服務器支持的數據利用TBlobStream則不同只要是程序能夠定義的數據格式它都能在BLOB字段中讀寫而不需要其它輔助工具
TBlobStream用構造方法Create建立數據庫域和BLOB流的聯接用Read或Write 方法訪問和改變域中的內容用Seek方法在域中定位用Truncate方法刪除域中當前位置起所有的數據
TBlobStream的屬性和方法
TBlobStream對象從TStream直接繼承沒有增添新的屬性它覆蓋了ReadWrite 和Seek方法提供了對BLOB字段的訪問操作它增添了Truncate方法以實現BLOB字段中的刪除操作
Read方法
聲明
function Read(var Buffer; Count: Longint)
Longint;
Read方法從數據庫域的當前位置起復制Count個字節的內容到Buffer中Buffer也必須至少分配Count個字節Read方法返回實際傳輸的字節數因為傳輸的字節數可能小於Count所以需要選擇符的邊界判斷
[] [] [] []
From:http://tw.wingwit.com/Article/program/Delphi/201311/25100.html