我有一个二进制文件,当我打开它时,我使用::StgOpenStorage
STGM_READWRITE | STGM_SHARE_DENY_WRITE | STGM_TRANSACTED
模式来获取名为rootStorage
的根存储。然后,我使用rootStorage.OpenStream
STGM_READWRITE | STGM_SHARE_EXCLUSIVE
模式获取名为subStream
的子流。
接下来,我用subStream.Wirte(...)
写了一些数据,并调用了subStream.Commit(STGC_DEFAULT)
,但是它无法在文件中写入数据。
我也试过了rootStorage.Commit(STGC_DEFAULT)
,可以写出数据。
但是当我使用UltraCompare Professional - Binary Compare将原始文件与我打开的文件进行比较时,在文件的末尾写了很多额外的数据。额外的数据似乎是从文件的开头。
我只想在打开文件时将一些数据写入文件。我该怎么办?
答案 0 :(得分:0)
二进制文件比较可能不适用于结构化存储文件。问题是结构化存储文件通常在其中分配了额外的空间 - 处理事务处理模式和扩展文件。如果要进行文件比较,则需要更多工作。您必须在每个文件中打开根存储,然后打开流,并对流进行二进制比较。
答案 1 :(得分:0)
我发现为什么我的文件中有额外的数据。
<强> 1 即可。我为什么要使用IStorage.Commit()
我使用STGM_READWRITE
模式创建存储空间。它被称为交易模式。在事务处理模式下,更改会累积,并且在完成显式提交操作之前不会反映在存储对象中。所以我需要致电rootStorage.Commit()
。
<强> 2 即可。为什么在调用IStorage.Commit(STGC_DEFAULT)
根据website:
OLE提供的复合文件使用两阶段提交过程,除非STGC_OVERWRITE
参数中指定了grfCommitFlags
。这个两阶段过程确保了在提交操作失败的情况下数据的健壮性。首先,所有新数据都写入底层文件中的未使用空间。如有必要,将为文件分配新空间。成功完成此步骤后,将使用单个扇区写入更新文件中的表,以指示将使用新数据代替旧数据。旧数据成为下一次提交时使用的可用空间。因此,旧数据可用,并且可以在提交更改时发生错误时进行恢复。如果指定了STGC_OVERWRITE
,则使用单阶段提交操作。