我在一款应用程序中遇到了一个反复出现的问题。它每隔30分钟左右就会产生一个相当简单的XML文件。这些数据文件通常很小 - 例如小于5KB。它不会锁定文件,而是每次都从头重新创建它。我很幸运地在测试机器上看到了这个问题,我观察到文件被损坏并设置为“nulls”(即十六进制中的00)。真正奇怪的是,它与应该有的长度完全相同。我试图在保存过程中非常仔细地操作:1.将xml写入与我要实际保存它的相同目录的临时文件中;2.使用MOVEFILE_WRITE_THROUGH设置执行Win32 MoveFile()(所以它应该阻塞直到移动真正完成),将文件移动以替换现有的数据文件;甚至我还锁定了一个Mutex来确保这不是线程问题。这种情况并不经常发生,可能只有1000个用户中的1个。我曾经观察到过在写入过程中发生电源故障或BSOD导致数据文件损坏的情况,例如,一个文件的32kb全部为空值。但是看起来它正在比我预期的更频繁地发生,考虑到在写入期间发生电源故障的几率以及我正在使用MOVEFILE_WRITE_THROUGH。你有什么想法吗? 约翰
一些问题的答案:
一些问题的答案:
Q: 为什么不直接写入文件?
A: 避免这种情况是为了使软件更少受到电源故障问题的影响。例如,当您正在写文件时发生崩溃/断电/蓝屏,那么您肯定会有一个损坏的文件。编写临时文件,然后移动它是一种常用且简单的方式,可以尽可能地确保原子文件操作(好吧,在不使用 NTFS 特定 API 的情况下尽可能接近)。我应该说,该软件是一个存档/备份系统,因此我必须比其他应用程序更加小心数据一致性。
Q: 这种情况是否在正常操作中发生?
A: 由于这个问题在实际情况中发生,我只有一些线索,所以我不能确定。我可以说,该软件在99.9%的时间内可靠工作。我想这就是我的问题所在:这只是因为 BSOD/电源故障引起的随机不幸还是一个错误?
Q: 哪个环境/操作系统:
A: XP、Vista、7、Server 200X。最可能是 NTFS,但也可能是 FAT32。
Q: 在移动文件之前我是否关闭了文件?
A: 是的。我正在使用 C++ 流,并在 MoveFile 之前调用 close()。
Q: 其他哪些进程正在访问该文件?
A: 没有由我管理的进程。显然,我无法控制病毒检查器、文件夹同步器等。该文件位于用户计算机的 AppData\Local 文件夹中。