文件内容损坏的原因

Joh*_*ohn 7 c++ windows file-io winapi corruption

我在野外有一个应用程序反复出现问题.

它有一个相当简单的XML文件,它偶尔会丢弃,就像每30分钟一样.

数据文件通常非常小 - 例如<5KB.

它没有锁定文件 - 它只是每次从头开始重新创建它.

我很幸运地看到问题发生在测试机器上,我观察到的是文件已损坏并设置为"nulls"(即十六进制中的00).真正奇怪的是它与它应该具有的正确长度完全相同.

我在保存过程中一直非常小心:

  1. 我将xml写入同一目录中的临时文件,因为我要真正保存它
  2. 我使用MOVEFILE_WRITE_THROUGH设置执行Win32 MoveFile()(因此它应该阻塞直到移动真正完整),移动文件以替换现有数据文件

我甚至锁定Mutex以确保这不是线程问题.

它通常不会发生,例如1000个用户中的1个.

现在我在过去观察到数据文件在写入过程中被电源故障或BSOD损坏,我看到像32kb的文件都是NULL.

但考虑到写入期间出现电源故障的可能性,以及特别是因为我正在使用MOVEFILE_WRITE_THROUGH,它似乎比我预期的要发生得更多.

有任何想法吗?

约翰


一些问题的答案:

  • 问:为什么不直接写入文件A:我避免这种情况使软件不易受到电源故障的影响.例如,你正在编写文件和崩溃/ powerfail/BSOD的一半,那么你肯定有一个损坏的文件.执行临时文件写入然后执行移动是确保尽可能执行原子文件操作的常用且简单的方法(尽管在不使用NTFS特定API的情况下尽可能合理).我应该说该软件是一个归档/备份系统,所以我必须更加注意数据一致性,而不是其他应用程序.

  • 问:这是否在正常操作期间发生?

  • 答:由于这个问题在野外发生,我只是在处理一些线索,所以我不确定.我可以说该软件在99.9%的时间内可靠运行.我猜这是我的问题的核心:这只是由BSOD /电源故障引起的随机不幸还是一个错误?

  • 问:什么环境/操作系统:

  • 答:XP,Vista,7,Server 200X.最有可能是NTFS,但可能是FAT32

  • 问:我在移动之前关闭了文件吗?

  • 答:是的.在使用MoveFile之前,我正在使用C++流并调用close()

  • 问:还有哪些进程正在访问该文件?

  • 答:没有我管理.显然,我无法控制病毒检查程序,文件夹同步器等.该文件位于用户计算机的AppData\Local文件夹中.

Tho*_*ews 0

以下是一些想法:

  • 在关键信息之后或长时间不写入之前刷新流。
  • 验证没有其他实体正在写入该文件。
  • 验证缓冲的数据没有被其他代码覆盖。
  • 在长时间未写入之间关闭文件。