为什么 IStream::Commit 无法将数据写入文件?
Why IStream::Commit failed to write data into a file?
我有一个二进制文件,当我打开它时,我使用 ::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 将原始文件与我打开的文件进行比较时,在文件末尾写入了很多额外的数据。额外的数据似乎来自文件的开头。
我只想在打开文件的同时写入一些数据。我该怎么办?
二进制文件比较可能不适用于结构化存储文件。问题是结构化存储文件通常在其中分配了额外的 space——以处理事务处理模式和增大文件。如果要进行文件比较,则需要更多的工作。您将必须打开每个文件中的根存储,然后打开流,并对流进行二进制比较。
我发现为什么我的文件中有额外的数据。
1。为什么要使用 IStorage.Commit()
我使用STGM_READWRITE
模式创建了一个存储。这称为事务处理模式。在事务模式下,更改会累积起来,直到完成显式提交操作后才会反映在存储对象中。所以我需要调用rootStorage.Commit()
。
2。为什么调用IStorage.Commit(STGC_DEFAULT)
后有多余的数据
根据这个website:
除非在 grfCommitFlags
参数中指定 STGC_OVERWRITE
,否则 OLE 提供的复合文件使用两阶段提交过程。这个两阶段过程可确保数据的稳健性,以防提交操作失败。首先,所有新数据都写入底层文件中未使用的space。如有必要,将新的 space 分配给该文件。成功完成此步骤后,文件中的 table 将使用单个扇区写入更新,以指示将使用新数据代替旧数据。旧数据变得免费 space 以在下一次提交时使用。因此,旧数据可用并且可以在提交更改时发生错误的情况下恢复。如果指定 STGC_OVERWRITE
,则使用单阶段提交操作。
我有一个二进制文件,当我打开它时,我使用 ::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 将原始文件与我打开的文件进行比较时,在文件末尾写入了很多额外的数据。额外的数据似乎来自文件的开头。
我只想在打开文件的同时写入一些数据。我该怎么办?
二进制文件比较可能不适用于结构化存储文件。问题是结构化存储文件通常在其中分配了额外的 space——以处理事务处理模式和增大文件。如果要进行文件比较,则需要更多的工作。您将必须打开每个文件中的根存储,然后打开流,并对流进行二进制比较。
我发现为什么我的文件中有额外的数据。
1。为什么要使用 IStorage.Commit()
我使用STGM_READWRITE
模式创建了一个存储。这称为事务处理模式。在事务模式下,更改会累积起来,直到完成显式提交操作后才会反映在存储对象中。所以我需要调用rootStorage.Commit()
。
2。为什么调用IStorage.Commit(STGC_DEFAULT)
根据这个website:
除非在 grfCommitFlags
参数中指定 STGC_OVERWRITE
,否则 OLE 提供的复合文件使用两阶段提交过程。这个两阶段过程可确保数据的稳健性,以防提交操作失败。首先,所有新数据都写入底层文件中未使用的space。如有必要,将新的 space 分配给该文件。成功完成此步骤后,文件中的 table 将使用单个扇区写入更新,以指示将使用新数据代替旧数据。旧数据变得免费 space 以在下一次提交时使用。因此,旧数据可用并且可以在提交更改时发生错误的情况下恢复。如果指定 STGC_OVERWRITE
,则使用单阶段提交操作。