文件损坏停电后

时间:2017-09-06 09:37:58

标签: .net vb.net filesystems system

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

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

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

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

您是否碰巧知道为什么会发生这种情况并建议采取解决方法?

2 个答案:

答案 0 :(得分:0)

根据文件,WriteAllBytes

  

创建一个新文件,将指定的字节数组写入该文件,然后关闭该文件。如果目标文件已存在,则会被覆盖。

假设当然是因为文件是由WriteAllBytes写入和关闭的,所以在此方法返回后它应该可靠地在磁盘上。但由于文件系统缓存策略可能有效,这是一个错误的假设。此外,即使文件系统将其缓存刷新到磁盘(以及"直写"文件系统),并且硬件已经返回"成功"指示,在数据实际物理写入磁盘之前,硬件缓存会导致延迟(尽管延迟非常短)。

如果您的数据非常重要,必须能够在停电后继续使用,请务必安装UPS。

所有这一切,等了一个小时拔出插头仍然看到你的文件损坏的声音可疑,可能它不是由于文件系统缓存。您的逻辑中可能存在错误,或内部或外部资源冲突。

我会尝试一些事情。

  1. 设计一个测试,在WriteAllBytes返回后立即验证文件的完整性,或者在您合理的时间后立即验证文件的完整性(最好不在您的应用程序内部,但在另一个应用程序旁边运行)。
  2. 尝试退出程序,等待几分钟,然后拔出插头,看看该文件中是否还有损坏。
  3. 如果您的应用程序也写入了其他文件,请验证其完整性。他们也表现出腐败吗?
  4. 尝试编写一个非常小的Windows测试程序,该程序调用{​​{1}}并在其运行时挂起并插上插头。该文件是否已损坏?
  5. 您的逻辑是否处理了电源故障"事件?这个逻辑是否会破坏你的文件。
  6. 是否涉及虚拟机?您是在拔出主机上的插头,还是在客户操作系统上模拟断电?
  7. 最后,WriteAllBytes是一种广泛使用的方法,并不复杂。我怀疑它是否会导致你的问题。

答案 1 :(得分:0)

经过一些搜索后,我发现我一直在硬盘上使用写缓存,因此一些文件在电源故障后无法写入。 由于性能在我的应用程序中非常关键,我决定让它保持启用状态,而是使用FileStreams在需要时执行fs.Flush(True)。

这通常被认为是一种好习惯吗?