STGM 常數

STGM 常數是旗標,指出建立和刪除物件的物件和存取模式的條件。 STGM 常數包含在 IStorageIStreamIPropertySetStorage 介面中,以及 StgCreateDocfileStgCreateStorageExStgCreateDocfileOnILockBytesStgOpenStorageStgOpenStorageEx 函式中。

這些元素通常會使用 OR運算子來合併。 它們會在群組中解譯,如下表所列。 從單一群組使用一個以上的元素並無效。

建立物件時,請使用建立群組中的旗標,例如 使用 StgCreateStorageExIStorage::CreateStream

如需交易的詳細資訊,請參閱一節。

群組 旗標
Access STGM_READ 0x00000000L
STGM_WRITE 0x00000001L
STGM_READWRITE 0x00000002L
共用 STGM_SHARE_DENY_NONE 0x00000040L
STGM_SHARE_DENY_READ 0x00000030L
STGM_SHARE_DENY_WRITE 0x00000020L
STGM_SHARE_EXCLUSIVE 0x00000010L
STGM_PRIORITY 0x00040000L
建立 STGM_CREATE 0x00001000L
STGM_CONVERT 0x00020000L
STGM_FAILIFTHERE 0x00000000L
交易 STGM_DIRECT 0x00000000L
STGM_TRANSACTED 0x00010000L
交易效能 STGM_NOSCRATCH 0x00100000L
STGM_NOSNAPSHOT 0x00200000L
直接 SWMR 和簡單 STGM_SIMPLE 0x08000000L
STGM_DIRECT_SWMR 0x00400000L
發行時刪除 STGM_DELETEONRELEASE 0x04000000L

STGM_READ

0x00000000L

表示物件是唯讀的,表示無法進行修改。 例如,如果使用 STGM_READ開啟資料流程物件,可能會呼叫 ISequentialStream::Read 方法,但 ISequentialStream::Write 方法可能不是。 同樣地,如果使用 STGM_READ開啟的儲存體物件,可能會呼叫 IStorage::OpenStreamIStorage::OpenStorage 方法,但 IStorage::CreateStreamIStorage::CreateStorage 方法可能無法呼叫。

STGM_WRITE

0x00000001L

可讓您儲存物件的變更,但不允許存取其資料。 提供的 IPropertyStorageIPropertySetStorage 介面實作不支援這個僅限寫入模式。

STGM_READWRITE

0x00000002L

啟用物件資料的存取和修改。 例如,如果在此模式中建立或開啟資料流程物件,就可以同時呼叫 IStream::ReadIStream::Write。 請注意,這個常數不是STGM_WRITESTGM_READ專案的簡單二進位OR運算。

STGM_SHARE_DENY_NONE

0x00000040L

指定後續的物件開啟不會遭到拒絕讀取或寫入存取。 如果未指定共用群組中的旗標,則會假設此旗標。

STGM_SHARE_DENY_READ

0x00000030L

防止其他人後續以 STGM_READ 模式開啟物件。 它通常用於根儲存體物件。

STGM_SHARE_DENY_WRITE

0x00000020L

防止其他人後續開啟物件以進行 STGM_WRITESTGM_READWRITE 存取。 在交易模式中,共用 STGM_SHARE_DENY_WRITESTGM_SHARE_EXCLUSIVE 可以大幅改善效能,因為它們不需要快照集。 如需交易的詳細資訊,請參閱一節。

STGM_SHARE_EXCLUSIVE

0x00000010L

防止其他人後續以任何模式開啟物件。 請注意,這個值不是STGM_SHARE_DENY_READSTGM_SHARE_DENY_WRITE值的簡單位OR運算。 在交易模式中,共用 STGM_SHARE_DENY_WRITESTGM_SHARE_EXCLUSIVE 可以大幅改善效能,因為它們不需要快照集。 如需交易的詳細資訊,請參閱一節。

STGM_PRIORITY

0x00040000L

開啟具有最近認可版本獨佔存取權的儲存體物件。 因此,當您以優先順序模式開啟物件時,其他使用者就無法認可物件的變更。 您會獲得複製作業的效能優勢,但會防止其他人認可變更。 限制物件在優先順序模式中開啟的時間。 您必須以優先順序模式指定 STGM_DIRECTSTGM_READ ,而且無法指定 STGM_DELETEONRELEASE。 只有在建立根物件時,STGM_DELETEONRELEASE才有效,例如使用 StgCreateStorageEx。 開啟現有的根物件時無效,例如使用 StgOpenStorageEx。 建立或開啟子項目時也無效,例如 使用 IStorage::OpenStorage

STGM_CREATE

0x00001000L

指出在新的物件取代它之前,應該移除現有的儲存物件或資料流程。 只有在成功移除現有物件時,才會指定這個旗標時,才會建立新的 物件。

嘗試建立時,會使用此旗標:

  • 磁片上的儲存體物件,但該名稱的檔案存在。
  • 儲存體物件內的物件,但具有指定名稱的物件存在。
  • 位元組陣列物件,但具有指定名稱的陣列物件存在。

此旗標無法搭配開啟作業使用,例如 StgOpenStorageExIStorage::OpenStream

STGM_CONVERT

0x00020000L

建立新的 物件,同時在名為 「Contents」 的資料流程中保留現有的資料。 在儲存體物件或位元組陣列的情況下,不論現有檔案或位元組陣列目前是否包含分層儲存物件,舊資料都會格式化為資料流程。 此旗標只能在建立根儲存體物件時使用。 它不能用在儲存體物件內;例如,在 IStorage::CreateStream中。 同時使用此旗標和 STGM_DELETEONRELEASE 旗標也無效。

STGM_FAILIFTHERE

0x00000000L

如果存在具有指定名稱的現有物件,則建立作業會失敗。 在此情況下,會傳回 STG_E_FILEALREADYEXISTS 。 這是預設建立模式;也就是說,如果未指定其他建立旗標, STGM_FAILIFTHERE隱含。

STGM_DIRECT

0x00000000L

表示在直接模式中,儲存體或資料流程專案的每個變更都會在發生時寫入。 如果未指定 STGM_DIRECTSTGM_TRANSACTED ,則為預設值。

STGM_TRANSACTED

0x00010000L

表示,在交易模式中,只有在呼叫明確認可作業時,才會緩衝變更並寫入。 若要忽略變更,請在IStreamIStorageIPropertyStorage介面中呼叫Revert方法。 IStorage的 COM 複合檔案實作不支援交易資料流程,這表示資料流程只能在直接模式中開啟,而您無法還原變更,不過支援交易的儲存體。 IPropertySetStorage的複合檔案、獨立和 NTFS 檔案系統實作同樣不支援交易的簡單屬性集,因為這些屬性集會儲存在資料流程中。 不過,支援在IPropertySetStorage::CreategrfFlags參數中指定PROPSETFLAG_NONSIMPLE旗標,以建立非簡單屬性集的交易。

STGM_NOSCRATCH

0x00100000L

表示在交易模式中,暫存暫存檔案通常用於儲存修改,直到呼叫 Commit 方法為止。 指定 STGM_NOSCRATCH 允許原始檔案的未使用部分做為工作區,而不是針對該用途建立新檔案。 這不會影響原始檔案中的資料,在某些情況下可能會導致效能改善。 若未指定 STGM_TRANSACTED,則指定此旗標無效,而且此旗標只能用於開啟根目錄。 如需 NoScratch 模式的詳細資訊,請參閱一節。

STGM_NOSNAPSHOT

0x00200000L

開啟具有 STGM_TRANSACTED 且不含 STGM_SHARE_EXCLUSIVESTGM_SHARE_DENY_WRITE的儲存體物件時,會使用此旗標。 在此情況下,指定 STGM_NOSNAPSHOT 可防止系統提供的實作建立檔案的快照集複本。 相反地,檔案的變更會寫入檔案的結尾。 除非在認可期間執行合併,而且檔案上只有一個目前的寫入器,否則不會回收未使用的空間。 在沒有快照模式中開啟檔案時,若未指定 STGM_NOSNAPSHOT,就無法執行另一個開啟作業。 此旗標只能在根開啟作業中使用。 如需 NoSnapshot 模式的詳細資訊,請參閱一節。

STGM_SIMPLE

0x08000000L

在有限但常用的案例中,提供更快速的複合檔案實作。 如需詳細資訊,請參閱<備註>一節。

STGM_DIRECT_SWMR

0x00400000L

支援單一寫入器、多執行緒檔案作業的直接模式。 如需詳細資訊,請參閱<備註>一節。

STGM_DELETEONRELEASE

0x04000000L

指出當根儲存體物件釋放時,基礎檔案會自動終結。 這項功能最適合用來建立暫存檔案。 此旗標只能在建立根物件時使用,例如使用 StgCreateStorageEx。 開啟根物件時無效,例如使用 StgOpenStorageEx,或建立或開啟子項目時,例如使用 IStorage::CreateStream。 同時使用此旗標和STGM_CONVERT旗標也無效。

備註

您可以結合這些旗標,但只能從每個相關旗標群組中選擇一個旗標。 一般而言,每個存取和共用群組中的一個旗標必須針對使用這些常數的所有函式和方法指定。 其他群組的旗標是選擇性的。

交易模式

指定 STGM_DIRECT旗標時,只能從存取和共用群組指定下列其中一個旗標組合。

    STGM_READ      | STGM_SHARE_DENY_WRITE
    STGM_READWRITE | STGM_SHARE_EXCLUSIVE
    STGM_READ      | STGM_PRIORITY

請注意,直接模式是由沒有 STGM_TRANSACTED所隱含。 也就是說,如果未指定 STGM_DIRECTSTGM_TRANSACTED ,則會假設 STGM_DIRECT

指定 STGM_TRANSACTED 旗標時,會在交易模式中建立或開啟物件。 在此模式中,在認可物件之前,對 物件的變更不會保存。 例如,呼叫 IStorage::Commit 方法之前,不會保存交易儲存體物件的變更。 如果儲存物件在呼叫 Commit 方法之前發行 (最終發行) ,或呼叫 IStorage::Revert 方法,則這類儲存物件的變更將會遺失。

在交易模式中建立或開啟物件時,實作必須同時保留原始資料和此資料的更新,以便在必要時還原更新。 這通常是藉由將變更寫入暫存區域,直到認可之前,或建立最近認可資料的複本,稱為快照集來執行。

在交易模式中開啟根儲存體物件時,可以控制臨時資料和快照集複本的位置和行為,以使用 STGM_NOSCRATCHSTGM_NOSNAPSHOT 旗標來優化效能。 (從 StgOpenStorageEx 函式取得根儲存體物件;從 IStorage::OpenStorage 方法取得的儲存體物件是子儲存體物件。) 一般而言,臨時資料和快照集會儲存在暫存檔中,與儲存體不同。

這些旗標的效果取決於存取根儲存體的讀取器和/或寫入器數目。

在「單一寫入器」案例中,交易模式儲存物件會開啟以供寫入存取,而且無法存取檔案的其他存取權。 也就是說,檔案會以 STGM_TRANSACTED開啟、 存取STGM_WRITESTGM_READWRITE,以及共用 STGM_SHARE_EXCLUSIVE。 在此情況下,儲存體物件的變更會寫入到臨時區域。 認可這些變更時,這些變更會複製到原始儲存體。 因此,如果未實際對儲存體物件進行任何變更,則不會有任何不必要的資料傳輸。

在「多寫入器」案例中,交易儲存物件會開啟以供寫入存取,但會以允許其他寫入器的方式共用。 也就是說,儲存體物件會以 STGM_TRANSACTED開啟、 存取STGM_WRITESTGM_READWRITE,以及共用 STGM_SHARE_DENY_READ。 如果改為指定 STGM_SHARE_DENY_NONE 共用,則案例為「多寫入器、多讀取器」。 在這些情況下,將會在開啟作業期間建立原始資料的快照集。 因此,即使未實際對儲存體進行任何變更,或未同時由另一個寫入器開啟,在開啟期間仍需要資料傳輸。 如此一來,在 STGM_SHARE_DENY_WRITESTGM_SHARE_EXCLUSIVE 模式中開啟儲存體物件,即可取得最佳的開啟時間效能。 如需當有多個寫入器時如何認可變更的詳細資訊,請參閱 IStorage::Commit

在「單一寫入器、多讀取器」案例中,交易儲存物件會開啟以供寫入存取,但會與讀取器共用。 也就是說,寫入器會開啟儲存體物件,其中包含 STGM_TRANSACTED存取STGM_READWRITESTGM_WRITE,以及共用 STGM_SHARE_DENY_WRITE。 讀取器會使用 STGM_TRANSACTED存取STGM_READ,以及共用 STGM_SHARE_DENY_NONE來開啟儲存體。 在此情況下,寫入器會使用臨時區域來儲存未認可的變更。 如同上述案例,讀取器會在建立資料的快照集複本時產生開啟時間效能負面影響。

一般而言,臨時區域是暫存檔,與原始資料分開。 當變更認可至原始檔案時,資料必須從暫存檔案傳輸。 若要避免此資料傳輸,可以指定 STGM_NOSCRATCH旗標。 指定此旗標時,儲存體物件檔案的部分會用於臨時區域,而不是個別的暫存檔案。 因此,可以快速地執行認可變更,因為需要少量資料傳輸。 缺點是儲存體檔案可能會變大,否則會變大,因為它必須成長為足以容納原始資料和臨時區域。 若要合併資料並移除此不必要的區域,請以交易模式重新開啟根儲存體,但未設定 STGM_NOSCRATCH 旗標。 然後,使用STGC_CONSOLIDATE旗標集呼叫IStorage::Commit

快照集區域就像臨時區域一樣,通常也會是暫存檔案,而且這也可能會受到 STGM 旗標的影響。 藉由指定 STGM_NOSNAPSHOT 旗標,不會建立個別的暫存快照集檔案。 相反地,原始資料永遠不會修改,即使每個物件有一或多個寫入器也一樣。 認可變更時,這些變更會新增至檔案,但原始資料會保持不變。 此模式會增加效率,因為它可藉由消除在開啟作業期間建立快照集的需求來降低執行時間。 不過,使用此模式可能會導致非常大的儲存體檔案,因為無法覆寫檔案中的資料。 這不會限制在 NoSnapshot 模式中開啟的檔案大小。

直接單一寫入器,Multiple-Reader模式

如所述,如果以交易模式開啟該物件,就可能會有單一寫入器和多個儲存體物件的讀取器。 您也可以藉由指定 STGM_DIRECT_SWMR 旗標,在直接模式中達到單一寫入器、多執行緒案例。

STGM_DIRECT_SWMR 模式中,有一個呼叫端可以開啟物件以進行讀取/寫入存取,而其他呼叫端同時開啟檔案以供唯讀存取。 與 STGM_TRANSACTED 旗標搭配使用這個旗標無效。 在此模式中,寫入器會以下列旗標開啟 物件:

| STGM_DIRECT_SWMR | STGM_READWRITESTGM_SHARE_DENYWRITE

而且每個讀取器都會以下列旗標開啟 物件:

| STGM_DIRECT_SWMR | STGM_READSTGM_SHARE_DENY_NONE

在此模式中,若要修改儲存物件,寫入器必須取得物件的獨佔存取權。 當所有讀取器都已關閉時,就可能這樣做。 寫入器會使用 IDirectWriterLock 介面來取得這個獨佔存取權。

簡單模式

簡單模式 (STGM_SIMPLE) 適用于執行完整儲存作業的應用程式。 這是有效率的,但具有下列條件約束:

  • 子儲存體不支援。
  • 無法封送處理儲存物件和從中取得的資料流程物件。
  • 每個資料流程的大小下限。 如果發行資料流程時,寫入資料流程的最小位元組少於最小,資料流程就會延伸至最小大小。 例如,特定 IStream 實作的大小下限為 4 KB。 建立資料流程並寫入 1 KB。 在該 IStream的最後一個版本中,資料流程大小會自動擴充至 4 KB。 接著,開啟資料流程並呼叫 IStream::Stat 方法會顯示大小為 4 KB。
  • 實作不支援 IStorageIStream 的所有方法。 如需詳細資訊,請參閱 IStorage - 複合檔案實作IStream - 複合檔案實作

封送處理 是在遠端程序呼叫內跨執行緒或進程界限封裝、解除封裝和傳送介面方法參數的程式, (RPC) 。 如需詳細資訊,請參閱封送處理詳細資料和介面封送處理

當建立作業以簡單模式取得儲存體物件時:

  • 您可以建立資料流程專案,但無法開啟。
  • 呼叫 IStorage::CreateStream來建立資料流程專案時,在釋放該資料流程物件之前,就無法建立另一個資料流程。
  • 寫入所有資料流程之後,請呼叫 IStorage::Commit 以排清變更。

當以簡單模式的 Open 作業取得儲存體物件時:

  • 一次只能開啟一個資料流程專案。
  • 無法藉由呼叫 IStream::SetSize 方法或搜尋或寫入超出資料流程結尾,來變更資料流程的大小。 不過,因為所有資料流程的大小都最低,所以即使原本寫入的資料較少,也可以使用最多該大小的資料流程。 若要判斷資料流程的大小,請使用 IStream::Stat 方法。

請注意,如果儲存專案是由非簡單模式的儲存物件修改,則無法再次以簡單模式開啟該儲存元素。

規格需求

需求
最低支援的用戶端
Windows 2000 Professional [僅限傳統型應用程式]
最低支援的伺服器
Windows 2000 Server [僅限桌面應用程式]
標頭
ObjBase.h

另請參閱

ISequentialStream::Read

IStorage

StgCreateDocfile

StgCreateDocfileOnILockBytes

StgCreateStorageEx

StgOpenStorage

StgOpenStorageEx

StgOpenStorageOnILockBytes