为什么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将原始文件与我打开的文件进行比较时,在文件末尾写入了大量额外的数据。额外的数据似乎来自文件的开头。
我只是想在打开文件的同时在文件中写入一些数据。我该怎么办?
二进制文件比较可能不适用于结构化存储文件。问题是,结构化存储文件中通常分配了额外的空间——用于处理事务处理模式和扩展文件。如果你想做一个文件比较,这将需要更多的工作。您必须打开每个文件中的根存储,然后打开流,并对流进行二进制比较。
我发现了为什么我的文件中有额外的数据。
1。为什么我应该使用IStorage.Commit()
我使用STGM_READWRITE
模式创建了一个存储。它被称为事务处理模式。在事务处理模式中,更改是累积的,并且在完成显式提交操作之前不会反映在存储对象中。所以我需要打电话给rootStorage.Commit()
。
2。为什么调用IStorage.Commit(STGC_DEFAULT)
后会有额外的数据
根据本网站:
OLE提供的复合文件使用两阶段提交过程,除非在grfCommitFlags
参数中指定了STGC_OVERWRITE
。这个分为两个阶段的过程确保了提交操作失败时数据的稳健性。首先,所有新数据都被写入底层文件中未使用的空间。如有必要,会为文件分配新的空间。一旦该步骤成功完成,文件中的表将使用单个扇区写入进行更新,以指示将使用新数据代替旧数据。旧数据将成为下一次提交时使用的可用空间。因此,旧数据是可用的,并且可以在提交更改时发生错误时进行恢复。如果指定了STGC_OVERWRITE
,则使用单相提交操作。
- C++数据文件、数组和计算赋值
- 数据文件的第二行未正确读取
- 在 C++/C 中使用 CURL 发出带有数据文件的 GET HTTP 请求
- 将数据文件读入结构 C++
- 引入流时C++数据文件未正确读取?
- 如何在数据文件中查找和显示内容
- 如何处理错误"E1696命令行错误:无法在Visual Studio 2017中打开元数据文件"mscorlib.dll"?
- 尝试读取数据文件,存储在数组中并打印所有元素,但它不起作用
- 将数据文件读入对象数组时出现问题
- C :数据文件有错误:预期的无限制ID
- C 和 C++:带有错误"Expected unqualified-id"的数据文件
- 如何在C 中读取一系列数据文件
- 从数据文件中读取每2个字节,并在向量中进行比较
- 写入单个大数据文件或多个小文件:哪个更快?
- 在读取数据文件时,如何找到用户字符串输入的字谜?
- 保护外部数据文件免受未经授权的修改
- C 读取数据文件
- C 如何将数据文件读取到结构或向量以及返回结构或向量
- 具有挑战性的数据文件格式,需要将其读取为包含类对象的数组的VAR
- C 中的Google单元测试:如何编写持久数据文件