IStream - 复合文件实现

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

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

若要基于全局内存创建简单流,请通过调用 API 函数 CreateStreamOnHGlobal 获取 IStream 指针。 若要在复合文件对象中获取 IStream 指针,请调用 StgCreateDocfileStgOpenStorage。 这些函数检索 IStorage 指针,然后使用该指针为 IStream 指针调用 CreateStreamOpenStream 在任一情况下,都使用相同的 IStream 实现代码。

注意

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

 

何时使用

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

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

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

注意

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

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

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