文档介绍:1、结构化存储
COM的结构化存储(struetured storage)机制,也称为永久存储
(persis tent st orage)机制。结构化存储可以说是软件存储技术的一个重要 进展,COM针对组件软件的需要,在文件系统的基础储也带来了另一个问题,那就是空间回收的管理。频繁地对同 一个复合文件进行修改、保存,则文件的尺寸总是在增长,原因在于删除对象 时, COM 只是把这些所占用的磁盘空间标记为“未用”,而没有释放这些磁盘 空间。当然COM以后可能会重用这些空间,但在重用之前,这些空间仍保留在 文件中。解决这个问题的方法是:首先创建一个新的复合文件,然后调用原先 根存储对象的CopyTo函数,把以前的树结构复制到新的根存储中,则新的复合 文件没有碎片空间。
Microsoft Access 或 Word 产生的文件就会出现这种情况。
10、结构化存储实现:复合文档
从结构化存储的对象结构可以看出,要在特定的系统平台上实现结构化 存储,关键在两方面:一是如何把根存储与底层存储介质结合起来,二是实现 存储对象和流对象。
复合文档通过一个被称为“LockBytes”的对象,把根存储与底层的存储介质联 系起来,其他的子对象则通过根存储与底层存储介质进行数据通信,从而实现 了整个结构化存储体系结构。底层介质不仅可以是磁盘文件,复合文档也允许 是内存空间,甚至是用户自定义的虚拟空间。LockBytes对象实际上是所有存 储介质的一种抽象表达方式,它把存储介质描述成一般化的字节序列,不管是 磁盘文件还是内存区域都可以按字节序列对待。
COM 库提供了缺省的基于文件句柄操作的 LockBytes 对象,我们可以利用此
LockBytes对象建立复合文件。COM库还提供了基于内存的LockBytes对象,我 们可以利用内存LockBytes对象建立内存中的复合文档。而且,COM还允许我 们实现自己的 LockBytes 对象,并在自定义 LockBytes 对象的基础上建立复合 文档。
11、复合文档 API 函数
创建复合文档API函数:StgCreateDocfile和 StgCreateDocfileOnLockBytes。
打开已经存在的复合文档 API 函数: StgOpenStorage 和 StgOpenStorageOnLockBytes。
在内存基础上创建 LockBytes 对象或者流对象的 API 函数: CreateILockBytesOnHGlobal、 GetHGlobalFromILockBytes、 CreateStreamOnHGlobal、GetHGlobalFromStream。
其他的 API 函数: StgIsStorageFile 和 StgSetTimes。
12、零内存保存特性和 IRootStorage 接口
复合文档通过 LockBytes 对象把根存储对象与底层的文件操作隔离开 来,所以我们在访问存储对象或者流对象时避开了文件句柄操作。当我们用事 务方式打开复合文件时,COM实际上用到了三个文件句柄,一个是复合文件句 柄,另一个是临时文件句柄,该临时文件记录了存储对象操作过程中的修改信 息,还有一个句柄用作在零内存情况下保存文件时预分配的文件句柄。
13、存储对象、流对象和文件的CLSID信息
通过ISt orage接口的Set Class函数可以为一个存储对象赋一个CLSID 标识符,并可通过Stat函数获取此CLSID值。实际上,存储对象通过此CLSID 值把它与一段可执行代码联系起来,当客户程序希望执行与存储对象相联系的 代码时,它利用CLSID值,并调用CoCreateInstamce函数创建一个COM对象, 再把存储对象交给COM对象,由它处理存储对象。这样的COM对象称为永久对 象(persistent object),它通常实现了 IPersist***接口,比如 IPersistFile、 IPersistStorage、IPersistStream 和 IPersistStreamInit 等,客户程序通 过这些接口进行数据交换。
COM也提供了几个API函数用于存储对象或者流对象执行与CLSID有关 的一些常规操作:
(1)WriteClassStg 和 ReadClassStg 函数封装了 IStorage::SetClass 和
IStorage::Stat成员函数,可以完成存储对象的CLSID的设置和获取操作。存 储对象只是个容器,它本身不包含数据信息,所以它的CLSID信息被写在其下 面的一个子流对象中,其名字为“ \x01Comp0bj”。
(2) WriteClassStm 和 ReadClassStm 函数