首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 第 20 章:開發物件導向資料管理功能(一)─ 串流物件總覽與 TStream 介面定義

     編輯:Delphi

前言:物件導向資料管理的重要性

面向對象技術是 90 年代主流,以 OO 方法建構並滲透 OO 風格的軟體擁有更高品質。在 OO 程式設計中,物件導向資料管理佔重要地位。Delphi 作為結合視覺化設計與 OO 語言的整合開發環境,其核心是元件(一種物件),應用程式完全由元件建構,開發高效能 Delphi 應用必然涉及物件導向資料管理技術。

物件導向資料管理包含兩面向:

  • 用物件管理資料
  • 管理各類資料物件(含物件與元件)

Delphi 兩方面表現優異。早期 Turbo Pascal 即有 Stream、Collection、Resource 等專用類別;Delphi 大幅增強,歸納為 Stream 物件(串流) 與 Filer 物件(讀寫器),廣泛應用於 VCL。它們不僅提供記憶體、外部儲存、Windows 資源中的物件管理,更支援資料庫 BLOB 欄位中的物件操作。

本章介紹 Stream 物件與 Filer 物件的實作原理、應用方法及在超媒體系統中的應用,對運用 Delphi 開發高階應用極為重要。

20.1 串流物件實作原理與應用

Stream 物件(串流物件)統稱 TStream、THandleStream、TFileStream、TMemoryStream、TResourceStream、TBlobStream 等。它們分別代表在各種媒介上儲存資料的能力,將各類資料型別(含物件與元件)在記憶體、外部儲存、資料庫欄位中的管理操作抽象為物件方法,充分發揮 OO 技術優勢,應用程式可輕易在各種 Stream 物件間複製資料。

20.1.1 TStream 物件

TStream 是能在各種媒介中儲存二進位資料的物件的抽象基底類別。繼承自 TStream 的物件用於在記憶體、Windows 資源檔、磁碟檔案、資料庫欄位等媒介儲存資料。

TStream 定義兩個屬性:Size 與 Position,分別以位元組為單位表示串流大小與目前指標位置。定義的方法用於在各種串流中讀、寫、相互複製二進位資料。所有 Stream 物件皆繼承自 TStream,故其定義的欄位與方法均可被呼叫。得益於 OO 動態連結特性,TStream 為各類串流提供統一介面,簡化使用;不同 Stream 物件抽象不同儲存媒介操作,TStream 方法為跨媒介資料複製提供最簡潔手段。

20.1.1.1 TStream 屬性與方法完整介面

1. Position 屬性

property Position: Longint;

指明串流中讀寫的目前位移量。

2. Size 屬性

property Size: Longint;

指明以位元組為單位的串流大小,唯讀。

3. CopyFrom 方法

function CopyFrom(Source: TStream; Count: Longint): Longint;

從 Source 複製 Count 位元組到目前串流,指標從目前位置移動 Count 位元組,回傳實際複製位元組數。

4. Read 方法(抽象虛擬方法)

function Read(var Buffer; Count: Longint): Longint; virtual; abstract;

從目前串流的目前位置複製 Count 位元組到 Buffer,指標後移 Count 位元組,回傳實際讀取位元組數。若回傳值小於 Count 表示讀取到達串流尾部。每個後繼 Stream 物件必須依其特定儲存媒介覆寫此方法。所有其他讀取方法(ReadBuffer、ReadComponent 等)最終皆呼叫 Read,動態連結優勢於此體現:後繼類別僅需覆寫 Read,其他讀取操作無需重新定義,TStream 提供統一介面。

5. ReadBuffer 方法

procedure ReadBuffer(var Buffer; Count: Longint);

從串流複製 Count 位元組到 Buffer,指標後移 Count。若超過尾部引發 EReadError 例外。

6. ReadComponent 方法

function ReadComponent(Instance: TComponent): TComponent;

從目前串流讀取 Instance 指定的元件,回傳所讀元件。建立 TReader 呼叫 ReadRootComponent。若 Instance=nil 依串流中類型資訊建立新元件並回傳。

7. ReadComponentRes 方法

function ReadComponentRes(Instance: TComponent): TComponent;

從串流讀取 Instance 指定元件,但串流目前位置必須是 WriteComponentRes 寫入元件的位置。先呼叫 ReadResHeader 再呼叫 ReadComponent。若無有效資源檔頭引發 EInvalidImage。Classes 單元亦有同名函數,基於應用程式資源建立串流執行相同操作。

8. ReadResHeader 方法

procedure ReadResHeader;

從串流目前位置讀取 Windows 資源檔頭,指標移至檔頭末尾。若無有效資源檔頭引發 EInvalidImage。ReadComponentRes 會自動呼叫,通常程式設計師無需自行呼叫。

9. Seek 方法(抽象虛擬方法)

function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract;

移動串流指標 Offset 位元組,起點由 Origin 指定。Offset 為負數時向串流頭部移動。Origin 取值對照表:

常數值Seek 起點Offset 取值
soFromBeginning0串流開頭正數
soFromCurrent1串流目前位置正數或負數
soFromEnd2串流結尾負數

10. Write 方法(抽象虛擬方法)

function Write(const Buffer; Count: Longint): Longint; virtual; abstract;

將 Buffer 中 Count 位元組寫入串流,指標向尾部移動 Count 位元組,回傳寫入位元組數。每個繼承 Stream 物件必須覆寫此方法提供特定儲存媒介寫入實作。所有其他寫入方法(WriteBuffer、WriteComponent 等)最終呼叫 Write 執行實際寫入。

11. WriteBuffer 方法

procedure WriteBuffer(const Buffer; Count: Longint);

功能類似 Write,呼叫 Write 執行實際寫入,若未寫入所有位元組引發 EWriteError 例外。

12. WriteComponent 方法

procedure WriteComponent(Instance: TComponent);

將 Instance 指定元件及其擁有的所有元件寫入串流。建立 TWriter 呼叫 WriteRootComponent。

13. WriteComponentRes 方法

procedure WriteComponentRes(const ResName: String; Instance: TComponent);

先寫入標準 Windows 資源檔頭,再寫入 Instance 指定元件。讀取需呼叫 ReadComponentRes。以 ResName 作為資源名,再呼叫 WriteComponent。

14. WriteDescendant 方法

procedure WriteDescendant(Instance, Ancestor: TComponent);

建立 TWriter 呼叫其 WriteDescendant 寫入 Instance。Instance 可為繼承自 Ancestor 元件的表單,或繼承表單中對應祖先表單中 Ancestor 元件的元件。

15. WriteDescendantRes 方法

procedure WriteDescendantRes(const ResName: String; Instance, Ancestor: TComponent);

寫入 Windows 資源檔頭(以 ResName 為資源名),再呼叫 WriteDescendant 寫入 Instance。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved