断电后文件损坏

File Corruption After power outage

我正在使用 File.WriteAllBytes 将更改写入文件。

如果在调用 WriteAllBytes 后发生断电,文件总是会损坏。 问题是,这不仅发生在我的保存函数执行期间,而且甚至在函数执行完成之后 - 有时甚至在我调用保存后一小时后发生。

我尝试使用 BinaryWriter,但我得到了相同的结果。我还尝试通过使用临时文件来实现解决方法。问题是 File.Copy 也有相同的行为 - 即如果我创建一个临时文件,并且在运行期间的某个时间发生断电,该文件将被损坏。

相比之下,我注意到即使我在写入文件后从任务管理器中终止了我的应用程序,即使在我调用 Write 几秒后发生这种情况,文件也不会损坏。

您是否碰巧知道为什么会发生这种情况并可能提出解决方法?

根据文档,WriteAllBytes

Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already exists, it is overwritten.

假设当然是因为文件由 WriteAllBytes 写入和关闭,那么它应该在该方法后立即可靠地存储在磁盘上 returns。但由于可能有效的文件系统缓存策略,这是一个错误的假设。此外,即使文件系统将其缓存刷新到磁盘(在 "write-through" 文件系统中)并且硬件已返回 "success" 指示,硬件缓存也会导致延迟(尽管延迟很短)在数据实际写入磁盘之前。

如果您的数据非常重要,必须在断电后仍然存在,请务必安装 UPS。

话虽如此,等了一个小时才拔下插头,但仍然看到您的文件已损坏,这听起来很可疑,好像这可能不是由于文件系统缓存造成的。您的逻辑中可能存在错误,或者存在内部或外部资源冲突。

我会尝试一些东西。

  1. 设计一个测试,在 WriteAllBytes returns 之后立即验证文件的完整性,或者在合理的情况下尽快验证文件的完整性(最好不在您的应用程序内部,而是在另一个应用程序中 运行 在旁边)。
  2. 尝试退出程序,等待几分钟,然后拔下插头,看看该文件是否仍然存在损坏。
  3. 如果您的应用程序还写入了其他文件,请验证它们的完整性。他们也表现出腐败吗?
  4. 尝试编写一个非常小的 windows 测试程序,调用 WriteAllBytes 并在 运行 时挂起并拔下插头。该文件是否已损坏?
  5. 您的逻辑是否处理 "power failure" 事件?该逻辑是否损坏了您的文件。
  6. 是否涉及虚拟机?你是在主机上拔插头,还是在客机上模拟停电OS?

最后,WriteAllBytes 是一种广泛使用的方法,并不复杂。我怀疑它会导致你的问题。

经过一些搜索我发现我一直在我的硬盘驱动器上使用写缓存,因此一些文件在断电后不会被写入。 由于性能在我的应用程序中非常关键,我决定将其保持启用状态,而是使用在需要时执行 fs.Flush(True) 的 FileStreams。

这通常被认为是一种好的做法吗?