COM結構化存儲

維基百科,自由的百科全書

COM結構化存儲(也稱「OLE結構化存儲」)是微軟在Windows作業系統上開發的一種技術,以在一個文件內存儲層次化的數據。嚴格講,術語「structured storage」是指COM的一套接口。並提供了有限形式的原子事務英語Atomic transaction數據訪問。

結構化存儲廣泛用於Microsoft Office應用程式。但從Office 2007開始默認使用基於XMLOffice Open XMLSQL Server也使用結構化存儲。

概述

結構化存儲是為了解決在一個文件中存放多個數據對象的本質性困難。當修改一個對象從而改變其尺寸時,如果這些對象在文件內是順序存放的,則被修改對象的尺寸擴大時所有在其後的對象都需要向後移動以騰出空間,被修改對象縮小尺寸時所有在其後的對象都需要向前移動。這樣的困難有很多種辦法應對,但應用程式開發者並不希望處理這樣低層次的二進制文件格式問題。

結構化存儲把文件系統的概念引入到文件內部。在文件內部構造一個樹狀層次結構。由存儲對象和流對象構成。根節點為根存儲,根存儲下面可以有子存儲或流對象。子存儲下面可以再有子存儲或流對象。存儲對象本身不包含信息,它是子存儲和流對象的容器。流對象是葉子節點,是數據的載體。

COM接口

簡介

結構化存儲提供了一種抽象,稱為「流」(stream),用COM接口IStream表示。一個流在概念上類似一個文件,使用IStream接口的方法來讀寫。流可以存在於內存中、文件中,或其它流中。另外一個重要抽象是「storage」,表示為COM接口IStorage。一個storage在概念上類似於文件系統的目錄。Storage可以包含流或其他storages。

一個應用程式如果要把幾個數據對象保存到一個文件中,一種辦法是打開一個IStorage以表示文件,然後把 每個對象存入單獨的IStream(這可通過標準COM接口IPersistStream)。

結構化存儲的事務機制,針對寫模式而不是讀模式。創建、打開存儲和流時可以指定事務模式。只有Commit後,所有的變化才提交到上級。revert可以恢復到上次commit以來的狀態。事務的實現是在內存中或臨時文件中保存文件拷貝的方式。事務可以嵌套。

增量訪問,可以減少保存文件的操作時間。對於文件碎片,調用根存儲CopyTo解決。

IStream接口

  class IStream::public IUnknown 

方法:

   Read
   Write
   Seek
   CopyTo
   Commit 把所有变化提交到包容该流对象的存储对象。
   Revert   rollback取消上次提交以来的所有操作。针对事务模式的流

IStorage接口

   class IStorage:public IUnknown  
   CreateStream 
   OpenStream 操作子流对象,返回IStream接口指针
   CreateStorage 
   OpenStorage 操作子存储对象,返回IStorage接口指针
   EnumElements 枚举所有的子流对象和子存储对象。
   commit
   Revert。针对事务模式的存储。
   Stat 获取存储对象的CLSID标识符
   SetClass 为存储对象赋一个CLSID标识符,并可通过Stat函数获取此CLSID值。通过此CLSID值把存储对象与一段可执行代码联系起来,当客户程序希望执行与存储对象相联系的代码时,它利用CLSID值,并调用 CoCreateInstamce函数创建一个COM对象,再把存储对象交给COM对象,由它处理存储对象。 

Windows API函數用於CLSID有關操作

  • WriteClassStg和ReadClassStg函數封裝了 IStorage::SetClass和IStorage::Stat成員函數,可以完成存儲對象的CLSID的設置和獲取操作。存儲對象只是個容器,它本身不包含數據信息,所以它的CLSID信息被寫在其下面的一個子流對象中,其名字為「\x01CompObj」。
  • WriteClassStm和ReadClassStm函數使用一致的格式在流對象的當前位置分別寫或者讀CLSID信息。通常情況下,在流的起始處放置CLSID信息。
  • GetClassFile函數返回一個與給定文件相聯繫的CLSID。Windows利用CLSID把數據文件與應用程式聯繫起來。

複合二進制文檔

Microsoft實現的一種稱為複合二進制文檔(Compound File Binary Format,簡稱「複合文檔」)的COM結構化存儲,廣泛用於結構化存儲實現。使用類似於FAT的結構表示存儲與流。文件片(chunk)被稱為扇區(sector)按需分配給新的流或增加尺寸的流。如果流被刪除或收縮尺寸,不再需要的扇區可以重新被其他流使用。

使用複合二進制文檔的應用程式有:

LockBytes對象

LockBytes對象是所有存儲介質的一種抽象。存儲介質描述稱為一般化的字節流,LockBytes對象負責從字節流中讀寫字節。複合文檔通過一個被稱為「LockBytes」的對象,把根存儲與底層的存儲介質聯繫起來,其他的子對象則通過根存儲與底層存儲介質進行數據通信,從而實現了整個結構化存儲體系結構。複合文檔通過LockBytes對象把根存儲對象與底層的文件操作隔離開來,在訪問存儲對象或者流對象時避開了文件句柄操作。

LockBytes對象實現了ILockBytes接口以提供基本的讀寫操作。COM庫提供了缺省的基於文件句柄的LockBytes對象,以及基於內存的LockBytes對象。

例如,可按照如下步驟創建基於內存的複合文檔。

  1. GlobalAlloc()獲得一個內存句柄
  2. CreateILockBytesOnHGlobal()創建一個LockBytes對象。這步類似於GlobleLock()
  3. StgCreateDocfileOnILockBytes()創建一個基於指定的LockBytes對象的複合文檔

其他方法:

  • 使用StgCreateDocfile()創建一個基於磁盤文件的複合文檔。
  • StgCreateDocfileOnLockBytes()
  • 使用StgOpenStorage()打開一個基於磁盤文件的複合文檔
  • 使用StgOpenStorageOnILockBytes()打開一個基於內存的複合文檔
  • GetHGlobalFromILockBytes
  • CreateStreamOnHGlobal
  • GetHGlobalFromStream
  • StgIsStorageFile
  • StgSetTimes

永久對象

概念上,永久對象與存儲對象和流對象沒有聯繫。永久對象可以把狀態信息存儲下來,以後可以重建這樣的對象,且恢復到以前的狀態。可以很方便地使用COM的結構化存儲機制或別的機制(如磁盤文件,系統註冊表,目錄服務,數據庫服務等)來保存永久對象的狀態。

COM定義了四個常用的永久接口:IPersistStorage, IPersistStream, IPersistStreamInit 和IPersistFile。前三個接口使用的結構化存儲機制。後一個接口直接使用文件。接口都包含三個基本函數

  • IsDirty:反映了自上次保存後是否被修改
  • Load:從存儲介質中裝入永久對象的狀態數據
  • Save:把永久對象的狀態數據保存到存儲介質中

類似功能產品

參考文獻

  1. ^ What is Native Structured Storage?. [2007-12-03]. (原始內容存檔於2007-09-27). 

外部連結