2011-08-20 80 views
0

我正在开发基于文档的桌面应用程序,该应用程序在用户保存文档时将相当大且复杂的文件写入磁盘。在这里做什么是防止数据损坏的最佳做法?有很多事情可能发生:覆盖文档文件

保存过程可能会失败一半,这当然是一个严重的应用程序错误,但在这种情况下,宁愿让旧文件比损坏的半写入文件。如果在文件写入过程中由于其他原因导致应用程序终止,则会发生同样的问题。

我能想到的最稳健的方法是在保存时使用临时文件,并且只有在新文件成功创建后才替换原始文件。但是我发现有几个操作(创建tempfile,保存到tempfile,删除原始文件,将tempfile移动到原始文件),可能会也可能不会失败,并且我最终会遇到相当复杂的try/catch语句来处理它们。

这种情况下是否有最佳做法/标准?例如,将原始文件复制到临时文件然后覆盖原始文件比保存到临时文件更好?

此外,如何以文件为基础的应用程序(在Windows中)的文件状态的原因?在用户关闭文档之前将文件保留为打开状态,或者快速打开文件并快速关闭它,是否更好?优点和缺点?

回答

1

通常情况下,文件洗牌舞蹈是这样的,旨在用包含新数据file.txt落得:

  • 写入file.txt.new
  • file.txt的移动到文件。 txt.old
  • 移动file.txt.new到FILE.TXT
  • 删除file.txt.old

在任何时候,你总是至少有一个有效的文件:

  • 如果只有file.txt的存在,你没有开始写file.txt.new
  • 如果file.txt的和file.txt.new存在,写入过程中可能失败 - file.txt应该是有效的旧副本。(如果你可以验证文件,你可以尝试加载新文件 - 这可能是失败的举动)
  • 如果file.txt.old和file.txt.new存在,第二个移动操作失败。您可以使用任一文件,具体取决于您是要新建还是旧版
  • 如果存在file.txt.old和file.txt,则删除操作失败。再次,你可以使用任何一个文件。

这是假设你在具有原子移动操作的文件系统上。如果情况并非如此,我相信程序是一样的,但您需要更加小心恢复过程。

+0

谢谢乔恩。假设文件可以被部分更新而不是完全重写(例如OPC包文件),您是否同意这只是在4个项目符号之前的一个额外步骤:将file.ext复制到file.ext.new以使模板从...开始?我使用可部分更新的格式的原因之一是性能,我担心预先复制整个旧文件可能会取消部分性能提升。需要测量我猜。 –

+0

@Anders:是的,这是有道理的。基本上,如果你不能容忍以*部分*更新的文件结束,你真的必须先复制它... –

0

从最后一个问题回答:

如果我们这里所说的是相当复杂的,大的文件,我就本人来说选择锁定文件作为读期间我可能不需要加载在视图中的所有数据,但只有一个用户现在需要。

一个第一:

  1. 保存在总是临时文件。
  2. 用新的替换旧的,如果失败了,考虑到你的应用程序是文档管理应用程序,你的主要目标失败了,所以最糟糕的情况下,但你有新的临时文件。所以在这个错误可以关闭你的应用程序并重新打开(严重错误),如果有临时文件重新打开控制,如果是的话,运行恢复数据,或多或少像VS在崩溃的情况下。
0

创建一个临时文件,然后用temp文件替换原始文件(后者在I/O方面是一个便宜的操作)是MFC文档持久化类使用的机制。我从来没有看到它失败。用户也没有报告过这样的问题。是的,那时的文件很大(它们也很复杂,但就I/O而言,这并不重要)。