IStream - 复合文件实施

IStream 接口支持读取和写入流对象的数据。 在结构化存储对象中,流对象包含数据和存储提供结构。 简单数据可以直接写入流,但更频繁地,流是嵌套在存储对象中的元素。 它们类似于标准文件。

IStream规范定义了比 COM 实现支持的更多功能。 例如, IStream 接口定义长度高达 2⁶⁴ 字节的流,需要 64 位查找指针。 但是,COM 实现仅支持长度高达 2 平方公里(4 GB)的流,读取和写入操作一次始终限制为 2ݫ 字节。 COM 实现也不支持流事务或区域锁定。

若要基于全局内存创建简单流,请通过调用 API 函数 CreateStreamOnHGlobal 获取 IStream 指针。 若要获取复合文件对象中的 IStream 指针,请调用 StgCreateDocfile StgOpenStorage。 这些函数检索 IStorage 指针,然后可以使用该指针为 IStream 指针调用 CreateStream 或 OpenStream。 无论哪种情况, 都使用相同的 IStream 实现代码。

注意

结构化存储的复合文件实现在 ISequentialStream 的 QueryInterface 方法上不成功,但它通过 IStream 接口指针包括读取写入方法。

 

何时使用

调用 IStream 的方法,以读取和写入流中的数据。

由于流对象可以封送给其他进程,因此应用程序可以在存储对象中共享数据,而无需使用全局内存。 在流对象的 COM 复合文件实现中,当两个进程具有共享内存访问时,COM 中的自定义封送设施会在新进程中创建原始对象的远程版本。 因此,远程版本不需要与原始进程通信才能执行其功能。

流对象的远程版本与原始流共享相同的查找指针。 如果不想共享查找指针,请使用 IStream::Clone 方法为远程进程提供流对象的副本。

注意

如果创建大于计算机内存中的堆的流对象,并且你正在对全局内存对象使用 HGLOBAL 句柄,则流对象在需要更多内存时在内部调用 GlobalRealloc 方法。 由于 GlobalRealloc 始终将数据从源复制到目标,因此将流对象从 20 MB 增加到 25 MB,例如,需要大量的时间。 这是因为复制的增量大小,并且由于磁盘交换而在计算机上内存小于 45 MB,则会恶化。

首选解决方案是实现 IStream 方法,该方法使用 VirtualAlloc 分配内存,而不是 GlobalAlloc。 这可以保留大量虚拟地址空间,然后根据需要在该地址空间内提交内存。 不会发生任何数据复制,并且仅在需要时提交内存。

GlobalRealloc替代方法是对流对象调用 IStream::SetSize 方法,以提前增加内存分配。 但是,这不像使用 VirtualAlloc 那样高效,如上所述。

 

方法

ISequentialStream::Read

将指定数目的字节从流对象读入到以当前搜索指针开始的内存。 如果在读取期间到达流的末尾,则此实现将返回S_OK。 (这与 MS-DOS FAT 文件系统中找到的“文件结尾”行为相同。

ISequentialStream::Write

将指定数字从字节写入流对象,从当前查找指针开始。 在此实现中,流对象不稀疏。 最终在磁盘上分配任何填充字节并将其分配给流。

IStream::Seek

将搜索指针更改为相对于流开始、流结束或当前搜索指针的新位置。

IStream::SetSize

更改流对象的大小。 在此实现中,不能保证分配的空间是连续的。

IStream::CopyTo

将指定的字节数从流中的当前搜索指针复制到其他流中的当前搜索指针。

IStream::Commit

IStream复合文件实现仅支持在直接模式下打开流,而不支持事务处理模式。 因此,除了将所有内存缓冲区刷新到下一个存储级别之外,此方法不起作用。

在此实现中,将更改提交到流并不重要,只需对存储对象提交更改。

IStream::Revert

此实现不支持事务处理流,因此对此方法的调用不起作用。

IStream::LockRegion

此实现不支持范围锁定,因此对此方法的调用不起作用。

IStream::UnlockRegion

删除以前使用 IStream::LockRegion 限制的一系列字节的访问限制。

IStream::Stat

检索此流的 STATSTG 结构

IStream::Clone

创建具有自己的搜索指针的一个新的流对象,该指针引用与原始流相同的字节。

简单模式 IStream 受以下约束的约束。

  • 如果流是从简单模式存储创建或打开的,则为简单模式。 如果存储是使用 grfMode 参数中设置的STGM_SIMPLE标志创建的或打开的,则存储是简单的模式。
  • 不支持 CloneCopyTo 方法。
  • 支持 Stat 方法,但必须指定STATFLAG_NONAME值。

IStream

IStorage

CreateStreamOnHGlobal

StgCreateDocfile

StgOpenStorage