第二十章開發Delphi物件式資料管理功能二

2021-03-04 09:54:06 字數 4625 閱讀 7446

20.1.6 tresourcestream物件

tresourcestream物件是另一類memorystream物件,它提供對windows 應用程式資源的訪問,因此稱它為資源流。tresourcesream也是從tcustommemorystream 繼承的。因此在tcustommemorystream物件的基礎上,定義了與指定資源模組或資源檔案建立連線的構造方法,並且還覆蓋了write,以實現向資源檔案中寫資料。

下面介紹tresourcestream的實現

1. 私有域

tresourcestream沒有定義新的屬性,,它們的定義如下:

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物件內部使用的。。它的實現如下:

procedure tresourcestream.initialize(instance: thandle; name, restype: pchar);

procedure error;

begin

raise eresnotfound.create(fmtloadstr(sresnotfound, [name]));

end;

begin

hresinfo := findresource(instance, name, restype);

if hresinfo = 0 then error;

hglobal := loadresource(instance, hresinfo);

if hglobal = 0 then error;

setpointer(lockresource(hglobal), sizeofresource(instance, hresinfo));

end;

該方法實現中,,然後呼叫loadresource將資源呼叫記憶體,並返回該資源在記憶體中的控制代碼,最後,將該資源複製到resourcestream中。方法的instance引數代表要呼叫的資源所在的模組控制代碼。模組可以是可執行檔案,也可以是動態鏈結庫。

如果在讀取資源時沒在模組中發現要找的資源則產生異常事件。

2. 構造方法create和createfromid

這兩個方法在實現上沒有大的不同。顧名思義,第乙個方法是通過資源名構造tresourcestream; 第二個方法通過資源id構造tresourcestream,而且在實現過程中,它們都呼叫了initialize方法。下面是它們的實現:

constructor tresourcestream.create(instance: thandle; const resname: string;

restype: pchar);

begin

inherited create;

initialize(instance, pchar(resname), restype);

end;

constructor tresourcestream.createfromid(instance: thandle; resid: integer;

restype: pchar);

begin

inherited create;

initialize(instance, pchar(resid), restype);

end;

這兩個方法中都有instance引數,該引數值的含義在insitialize中介紹過。

3. write方法

tresourcestream的write方法只完成一件事,就產生這個異常事件,其實現如下:

function tresourcestream.write(const buffer; count: longint): longint;

begin

raise estreamerror.createres(scantwriteresourcestreamerror);

end;

從方法實現中可以看到,tsourcestream物件是不允許寫資料的。一旦往資源流中寫資料將產生異常事件。

4. 析構方法destroy

該方法產生給資源解鎖,然後釋放該資源,最後呼叫繼承的destroy方法釋放resourcestream。其實現如下:

destructor

begin

unlockresource(hglobal);

freeresource(hresinfo);

inherited destroy;

end;

回顧initialize方法,我們不難發現:

● resourcestream沒有額外地給資源重新分配記憶體,而是直接使用hglobal控制代碼所指的記憶體域

● resourcestream中的資源在流的生存期,始終是lock狀態,因此要根據windows 的記憶體使用規則合理安排resourcestream的使用

● resourcestream只是用於訪問應用程式和動態鏈結庫中的資源的

在classes在單元中提供了internalread***ponentres函式,該函式使用了tresourcestream物件從delphi應用程式中讀取部件。delphi是將窗體和部件資訊放在模組資源的rcdata段的。

20.1.7 tblobstream物件

從delphi 資料庫開發平台這個意義上說,tblobstream 物件是個很重要的物件。tblobstream物件提供了修改tblobfield、tbytesfield或tvarbytesfield中資料的技術。開發者可以象對待檔案或流那樣在資料庫域中讀寫資料。

傳統資料庫發展的乙個重要趨向是往多**資料庫發展。目前比較著名和流行的資料庫都支援多**功能,多**資料儲存中的一大難點是資料結構不規則,資料量大。各大資料庫產品是採用blob技術解決多**資料儲存中的問題。

delphi的tblobstream物件的意義就在於:一方面可以使delphi應用程式充分利用多**資料庫的資料管理能力;另一方面又能利用object pascal的強大程式設計能力給多**資料庫提供全方向的功能擴充套件餘地。

使用tblobstream物件可以在多**資料庫的blob欄位儲存任意格式的資料。一般說來,許多多**資料庫只能支援影象、語音或者ole伺服器支援的資料。利用tblobstream則不同,只要是程式能夠定義的資料格式,它都能在blob欄位中讀寫,而不需要其它輔助工具。

tblobstream用構造方法create建立資料庫域和blob流的聯接。用read或write 方法訪問和改變域中的內容;用seek方法,在域中定位;用truncate方法刪除域中當前位置起所有的資料。

20.1.7.1 tblobstream的屬性和方法

tblobstream物件從tstream直接繼承,沒有增添新的屬性。它覆蓋了read、write 和seek方法,提供了對blob欄位的訪問操作;它增添了truncate方法以實現blob欄位中的刪除操作。

1. read方法

宣告:function read(var buffer; count: longint): longint;

read方法從資料庫域的當前位置起複製count個位元組的內容到buffer中。buffer也必須至少分配count個位元組。read方法返回實際傳輸的位元組數,因為傳輸的位元組數可能小於count,所以需要選擇符的邊界判斷。

2. write方法

宣告:function write(const buffer; count: longint); override; longint;

write方法從buffer中向資料庫域的當前位置複製count個位元組的內容。buffer必須分配有count個位元組的記憶體空間,函式返回實際傳輸的位元組數,傳輸過程也要進行選擇符邊界判斷。

3. seek方法

宣告:function seek(offset: longint; origin: word): longint;

seek方法重新設定blob流中的指標位置。如果origin的值是sofrombeginning,則新的指標位置是offset; 如origin的值是sofromcurrent,則新的指標位置是position+offset;如果origin的值是sofromcurrent,則新的指標位置是size+offset。函式返回新的指標位置值。

當origin為0(sofrombegin)時,offset的值必須大於等於零; 當origin的值為2(sofromend),offset的值必須小於等於零。

4. truncate方法

宣告:procedure truncate;

truncate方法撤消tblobfield、tbytesfield或tvarbytesfield中從當前位置起的資料。

5. create方法

宣告:constructor create(field: tblobfield; mode: tblobstreammode);

第二十章倉儲合同

第三百八十一條倉儲合同是保管人儲存存貨人交付的倉儲物,存貨人支付倉儲費的合同。第三百八十二條倉儲合同自成立時生效。第三百八十三條儲存易燃 易爆 有毒 有腐蝕性 有放射性等危險物品或者易變質物品,存貨人應當說明該物品的性質,提供有關資料。存貨人違反前款規定的,保管人可以拒收倉儲物,也可以採取相應措施以...

公司金融第二十章

第二十章股利分配決策 第一節股利的種類 一丶股利的不同種類 按照目前教科書以及實際實施的股利分配,股利的種類通常有 現金股利 股利和其他形式的股利 實物股利 回購 分拆 二 股利形式的討論 股利分配所體現的是公司與股東的之間的委託 關係。從資金交易角度講,公司與股東之間由股權交易所引起的經濟關係主要...

v第二十章經濟廣告

學習要點 一 認識經濟廣告的作用 二 掌握經濟廣告選擇資訊的知識 三 進行文字廣告的寫作實踐 難點解析 一 廣告與商品說明書的區別 商品說明書不就是廣告嗎?不,商品說明書雖然多少能起到廣告的作用,甚至在寫作時 的確有廣告的意識。但兩者的區別是明顯的,我們學習寫作,不能不把二者分開來。本章在第三節 經...