STGM 常量

STGM 常量是指示创建和删除对象和访问模式的条件的标志。 STGM 常量包含在 IStorageIStreamIPropertySetStorage 接口以及 StgCreateDocfileStgCreateStorageExStgCreateDocfileOnILockBytesStgOpenStorageStgOpenStorageEx 函数中。

这些元素通常使用 ORoperator 组合。 它们按下表中列出的组进行解释。 使用单个组中的多个元素无效。

创建对象时,使用创建组中的标志,例如使用 StgCreateStorageExIStorage::CreateStream

有关事务的详细信息,请参阅“备注”部分。

Group 标志
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元素的简单二进制操作。

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值的简单按位操作。 在事务模式下, 共享STGM_SHARE_DENY_WRITESTGM_SHARE_EXCLUSIVE 可以显著提高性能,因为它们不需要快照。 有关事务的详细信息,请参阅“备注”部分。

STGM_PRIORITY

0x00040000L

打开具有对最近提交的版本的独占访问权限的存储对象。 因此,在优先级模式下打开对象时,其他用户无法提交对对象的更改。 你可以获得复制操作的性能优势,但会阻止其他人提交更改。 限制对象在优先级模式下打开的时间。 必须使用优先级模式指定 STGM_DIRECTSTGM_READ ,并且不能指定 STGM_DELETEONRELEASESTGM_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_DIRECT 也没有 指定STGM_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) 中跨线程或进程边界打包、解压缩和发送接口方法参数的过程。 有关详细信息,请参阅 封送处理详细信息接口封送处理

在简单模式下通过 Create 操作获取存储对象时:

在简单模式下通过 Open 操作获取存储对象时:

  • 一次只能打开一个流元素。
  • 无法通过调用 IStream::SetSize 方法或在流末尾外查找或写入来更改流的大小。 但是,由于所有流的大小都最低,因此即使最初写入的数据较少,也有可能使用最大大小的流。 若要确定流的大小,请使用 IStream::Stat 方法。

请注意,如果存储元素由不处于简单模式的存储对象修改,则不能再次在简单模式下打开该存储元素。

要求

要求
最低受支持的客户端
Windows 2000 Professional [仅限桌面应用]
最低受支持的服务器
Windows 2000 Server [仅限桌面应用]
标头
ObjBase.h

另请参阅

ISequentialStream::Read

IStorage

StgCreateDocfile

StgCreateDocfileOnILockBytes

StgCreateStorageEx

StgOpenStorage

StgOpenStorageEx

StgOpenStorageOnILockBytes