Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 覆盖文档文件_C#_.net_File Io - Fatal编程技术网

C# 覆盖文档文件

C# 覆盖文档文件,c#,.net,file-io,C#,.net,File Io,我正在开发一个基于文档的桌面应用程序,当用户保存文档时,它会将一个相当大且复杂的文件写入磁盘。防止数据损坏的最佳做法是什么?有许多事情可能发生: 保存过程可能会中途失败,这当然是一个严重的应用程序错误,但在这种情况下,人们宁愿保留旧文件,也不愿保留已损坏的半写文件。如果应用程序在文件写入过程中由于其他原因终止,也会出现同样的问题 我能想到的最可靠的方法是在保存时使用临时文件,并且仅在成功创建新文件后替换原始文件。但我发现有几个操作(创建tempfile、保存到tempfile、删除origina

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

保存过程可能会中途失败,这当然是一个严重的应用程序错误,但在这种情况下,人们宁愿保留旧文件,也不愿保留已损坏的半写文件。如果应用程序在文件写入过程中由于其他原因终止,也会出现同样的问题

我能想到的最可靠的方法是在保存时使用临时文件,并且仅在成功创建新文件后替换原始文件。但我发现有几个操作(创建tempfile、保存到tempfile、删除original、将tempfile移动到original)可能会失败,也可能不会失败,为了正确处理这些操作,我最终会遇到一大堆复杂的try/catch语句

该场景是否有最佳实践/标准?例如,将原件复制到临时文件,然后覆盖原件是否比保存到临时文件更好


另外,在基于文档的应用程序(在windows中)中,如何解释文件的状态?在用户关闭文档之前,最好让应用程序打开文件以供写入,还是在打开文件时快速进入一个读取窗口,然后再次快速关闭它?利与弊

回答最后一个问题:

如果我们在这里谈论的是相当复杂和大的文件,我个人会选择锁定文件,因为在读取过程中,我可能不需要加载视图中的所有数据,但现在只需要一个用户需要的数据

首先:

  • 始终保存在临时文件中
  • 用新的替换旧的,如果失败了,考虑到您的应用程序是文档管理应用程序,您的主要目标失败了,所以这是有史以来最糟糕的情况,但您有新的临时文件。因此,在出现此错误时,可以关闭应用程序并重新打开(严重错误),如果存在临时文件,则可以重新打开控件,如果是,则可以运行数据恢复,这或多或少与VS在崩溃时所做的相同

  • 通常,文件洗牌舞是这样的,目的是以包含新数据的
    file.txt
    结束:

    • 写入file.txt.new
    • 将file.txt移到file.txt.old
    • 将file.txt.new移动到file.txt
    • 删除文件.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存在,则删除操作失败。同样,您可以使用任意一个文件

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

    创建一个临时文件,然后用临时文件替换原始文件(后者在I/O方面是一个便宜的操作)是MFC文档持久性类使用的机制。我从未见过失败。用户也没有报告此类问题。是的,当时的文档很大(它们也很复杂,但这与I/O无关)。

    谢谢Jon。假设文件可以部分更新,而不是完全重写(例如OPC软件包文件),您是否同意这只是意味着在4个项目符号之前需要额外的步骤:将file.ext复制到file.ext.new以创建模板?我使用可以部分更新的格式的原因之一是性能,我担心预复制整个旧文件可能会抵消一些性能增益。我想需要测量。@Anders:是的,那是有道理的。基本上,如果你不能容忍一个部分更新的文件,你必须先复制它。。。