我在野外遇到一个反复出现的问题。
它有一个相当简单的XML文件,它每隔30分钟就会有一次转储。
数据文件通常很小 – 例如<5KB。
它没有locking文件 – 每次从头开始重新创build。
我很幸运地看到testing机器上发生的问题,我观察到的是该文件已损坏,并设置为“空”(即hex00)。 真奇怪的是,它的长度恰恰相反。
我在保存过程中非常小心:
我甚至locking了一个Mutex,以确保这不是一个线程问题。
这种情况不会经常发生,例如1000个用户中有1个。
现在我已经观察到数据文件在写入过程中被电源故障或BSOD损坏,而且我已经看到文件的32kb全部为NULL。
但是看起来好像比我想象的要多,因为在写入过程中电源故障的可能性,特别是因为我使用MOVEFILE_WRITE_THROUGH。
有任何想法吗?
约翰
一些问题的答案:
问:为什么不直接写入文件答:我避免了这个问题,使软件不易受电源故障的影响。 例如,你通过写文件和崩溃/ powerfail / BSOD一半,那么你肯定有一个损坏的文件。 执行临时文件写入然后移动是确保您尽可能执行primefaces文件操作的一种常用且简单的方法(当然,如果不使用NTFS特定的API,则尽可能合理)。 我应该说这个软件是一个归档/备份系统,所以我必须比其他应用程序更加关心数据的一致性。
问:在正常操作中是否发生这种情况?
答:由于这个问题是在野外发生的,我只用了一些线索,所以我不确定。 我可以说99.9%的时间软件可靠地工作。 我想这是我的问题的琐碎:这是BSOD /电源故障造成的随机不吉利还是它的错误?
问:什么样的环境/操作系统:
答:XP,Vista,7,Server 200X。 最有可能的NTFS,但可能是FAT32
问:我在移动之前closures文件
答:是的。 我使用C ++stream并在执行MoveFile之前调用close()
问:还有哪些进程正在访问该文件?
根据我的经验,这可能是由Windows中的文件缓存引起的。 您应该尝试使用CreateFile()
和FILE_FLAG_WRITE_THROUGH
传入来保存文件。通过这种方式保存文件可以确保文件将落在硬盘上。
我wr了一个小程序来测试这个。 如果程序使用std::ofstream
创建文件并使用MoveFileEx()
和MOVEFILE_WRITE_THROUGH
来移动该文件,则在文件移动完成后立即关闭(不关闭)虚拟机几乎每次都会损坏文件; 否则,如果程序使用FILE_FLAG_WRITE_THROUGH
CreateFile()
来创建文件,并再次做同样的事情,文件没有损坏(我测试了大约10次,但没有发生)。
经过这些简单的测试,我认为你应该尝试使用FILE_FLAG_WRITE_THROUGH
CreateFile()
来解决你的问题。
更多信息:
文件缓存(Windows)
Windows内部,第6版,第11章缓存管理器
这里有一些想法: