2011-08-20 108 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而言,這並不重要)。