人人做人人澡人人爽欧美,国产主播一区二区,久久久精品五月天,羞羞视频在线观看免费

當前位置:蘿卜系統下載站 > 技術開發教程 > 詳細頁面

第二10章 開發Delphi對象式數據管理技巧(二)

第二10章 開發Delphi對象式數據管理技巧(二)

更新時間:2022-07-09 文章作者:未知 信息來源:網絡 閱讀次數:

20.1.6 TResourceStream對象 

  TResourceStream對象是另一類MemoryStream對象,它提供對Windows 應用程序資源的訪問,因此稱它為資源流。TResourceSream也是從TCustomMemoryStream 繼承的。因此在TCustomMemoryStream對象的基礎上,定義了與指定資源模塊或資源文件建立連接的構造方法,并且還覆蓋了Write,以實現向資源文件中寫數據。

  下面介紹TResourceStream的實現

  1. 私有域

  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 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; 

  該方法實現中,首先調用Windows函數FoundResource得到由參數Instance指定的模塊中的名為Name和類型為ResType的資源,然后調用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 TResourceStream.Destroy;

  begin

  UnlockResource(HGlobal);

  FreeResource(HResInfo);

  inherited Destroy;

  end; 

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

  ● ResourceStream沒有額外地給資源重新分配內存,而是直接使用HGlobal句柄所指 的內存域

  ● ResourceStream中的資源在流的生存期,始終是Lock狀態,因此要根據Windows 的內存使用規則合理安排ResourceStream的使用

  ● ResourceStream只是用于訪問應用程序和動態鏈接庫中的資源的 

  在Classes在單元中提供了InternalReadComponentRes函數,該函數使用了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);

  Create方法使用Field參數建立BLOB流與BLOB字段的聯接。Mode 的值可為bmRead、bmWrite和bmReadWrite!

  20.1.7.2 TBlobStream的實現原理 

  說明TBlobStream對象的實現原理,不可避免地要涉及它的私有域,下面是私有域的定義: 

  TBlobStream = class(TStream)

  private

  FField: TBlobField;

  FDataSet: TDataSet;

  FRecord: PChar;

  FBuffer: PChar;

  FFieldNo: Integer;

  FOpened: Boolean;

  FModified: Boolean;

  FPosition: Longint;

  …

  public

  …

  end; 

  FField是與BLOB流相聯的數據庫BLOB域,該域用于BLOB流的內部訪問。FDataSet是代表FField所在的數據庫,它可以是TTable部件,也可以是TQuery 部件。FRecord和FBuffer都是BLOB流內部使用的緩沖區,用于存儲FField所在記錄的數據,該數據記錄中不包含BLOB數據,TBlobStream使用FRecord作為調用BDE API函數的參數值。FFieldNo代表BLOB字段的字段號,也用于BDE API的參數傳遞,FOpened和FMocified都是狀態信息,FPosition表示BLOB流的當前位置,下面介紹TBlobStream方法實現。

[1] [2]  下一頁

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

網站地圖xml | 網站地圖html
主站蜘蛛池模板: 新营市| 北宁市| 盘锦市| 米泉市| 偏关县| 阳泉市| 无棣县| 上栗县| 吉水县| 青神县| 泰安市| 延津县| 岢岚县| 浪卡子县| 深水埗区| 仁布县| 北安市| 安国市| 聊城市| 乌鲁木齐市| 泗洪县| 峨眉山市| 普兰店市| 安新县| 竹北市| 南开区| 五家渠市| 汪清县| 黄山市| 洛隆县| 两当县| 安西县| 巴彦淖尔市| 许昌县| 龙里县| 雷州市| 厦门市| 庆元县| 吐鲁番市| 九龙县| 来凤县|