2

我有一个应用程序,它使用 XElement 对象的 .Save("path") 方法每 500 毫秒将数据存储在 XML 文件中。问题是:当突然关机时,文件的内容被删除,所以下次运行应用程序时该文件无法使用。

如何防止/确保数据不会丢失?PS:我在 Windows 7 下使用 .NET 2010 C#

我做了一个实验:每次都没有写入我创建的同一个 data.xml 文件(通过从原始文件复制)一个新文件,并且当从 data.xml 文件复制时断电时它会损坏所有以前创建的文件?!?!?

4

3 回答 3

6

假设您的文件是data.xml. 不要一直写入,而是写入data.xml临时文件data.xml.tmp,完成后将其重命名为data.xml. 但是如果您已经有一个文件,重命名将不起作用data.xml,因此您需要先将其删除,然后重命名临时文件。

这样,data.xml将包含最后的安全数据。如果您突然关机,不完整的文件将是临时的data.xml.tmp. 如果您的程序稍后尝试读取文件并且没有data.xml文件,则意味着在删除和重命名操作之间发生了关闭,因此您将不得不读取临时文件。我们知道它是安全的,否则会有一个data.xml文件。

于 2013-04-22T20:35:23.510 回答
1

您可以使用两阶段提交:

  1. 将新 XML 写入具有不同名称的文件
  2. 删除旧文件
  3. 将新文件重命名为旧名称

这样,总会有至少一个完整的文件。
如果您重新启动,并且标准名称不存在,请检查不同的名称。

于 2013-04-22T20:35:38.107 回答
0

这可能是一个生命的救星,但只需付出更多的努力。应该有一个单独的过程

  • 每当文件更新时,自动备份到其存储区。
  • 它在内部维护一个链表中的两个版本。
  • 如果文件被更新,那么最新的应该被更新到,并且可以删除HEAD using linkedList.AddFirst()指向的最小版本。TAILlinkedList.RemoveLast()
  • 当然,它应该在启动期间扫描并加载有关存储中可用的最新版本的存储。

在硬关机的情况下,下次系统启动时,这个进程应该检查文件是否有效/损坏。如果损坏,则HEAD使用FileChanged简单的FileSystemWatcher.

这种方法经过了很好的测试。

看到的问题

  • 如果在更新时发生硬关机HEAD怎么办?-- 好吧,我们在旁边的藏匿处有另一个版本HEAD
  • 如果在更新HEAD存储为空时发生硬关机怎么办?- 我们知道文件在更新时是有效的HEAD。该进程将在下次启动时再次尝试复制,因为它没有损坏。
  • 如果存储为空且文件已损坏怎么办?——这是死坑,没有解决办法。但这种情况只有在文件损坏发生后部署此恢复过程时才会发生。
于 2019-03-19T09:36:22.597 回答