关于将文件活动刷新到磁盘的 Windows Win32 C++ 问题。
我有一个外部应用程序(使用 CreateProcess 运行)来创建一些文件。即,当它返回时,它将创建一个包含一些内容的文件。
在继续之前,如何确保进程创建的文件确实刷新到磁盘?
我的意思不是 C++ 缓冲区,而是真正刷新磁盘(例如 FlushFileBuffers)。
请记住,我无权访问任何文件 HANDLE - 这当然隐藏在外部进程中。
我想我可以打开我自己的文件句柄,然后使用 FlushFileBuffers,但不清楚这是否可行(因为我的句柄实际上不包含任何需要刷新的东西)。
最后,我希望它在非管理员用户空间中运行,因此我不能在整个卷上使用 FlushFileBuffers。
有任何想法吗?
更新:为什么我认为这是一个问题?
我正在开发数据备份应用程序。本质上,它必须按照描述创建一些文件。然后它必须更新它的内部数据库(使用 SQLite 嵌入式数据库)。
我最近遇到了蓝屏期间发生的数据损坏问题(其原因与我的应用程序无关)。
我关心的是系统崩溃期间的应用程序完整性。是的,我确实关心这一点,因为这个应用程序是一个数据备份应用程序。
我关心的用例是这样的:
- 使用外部进程创建一个小数据文件。此写入在 OS 缓存中等待写入磁盘。
- 我更新数据库并提交。这是磁盘活动。此写入也在 OS 缓存中等待。
- 发生系统故障。
在我看来,我们现在处于潜在的竞争状态。如果“1”被刷新而“2”没有被刷新,那么我们很好(因为数据库事务没有被提交)。如果两者都没有被刷新或都被刷新,那么我们也可以。
据我了解,写入将是不确定的。即,我不知道操作系统会保证在“2”之前写“1”。(我错了吗?)
所以,如果“2”被刷新,但“1”没有被刷新,那么我们就有问题了。
我观察到数据库已正确更新,但文件中有垃圾:最后三分之二的数据是二进制“零”。现在,我不知道当您在蓝屏时刷新文件部分时会是什么样子,但如果它看起来像这样,我不会感到惊讶。
我可以保证这是原因吗?不,我不能保证这一点。我只是在猜测。可能只是由于磁盘故障或蓝屏导致文件“自然”损坏。
关于性能,这是我相信我可以处理的事情。
例如,SQLite 的默认行为是在每次提交事务时执行完整文件刷新(使用 FlushFileBuffers)。他们很清楚,如果您不这样做,那么在系统崩溃时,您的数据库可能已损坏。
另外,我相信我可以通过仅在“检查点”刷新来减轻性能影响。例如,写入 50 个文件,刷新批次,然后写入数据库。
这一切成为问题的可能性有多大?打败我。但是,我的应用程序很可能会在系统故障时或前后存档,因此您可能更可能认为。
希望这能解释为什么我不想这样做。