Перезапись файла документа - PullRequest
0 голосов
/ 20 августа 2011

Я разрабатываю настольное приложение на основе документов, которое записывает довольно большой и сложный файл на диск, когда пользователь сохраняет свой документ. Какова наилучшая практика для предотвращения повреждения данных? Есть несколько вещей, которые могут произойти:

Процесс сохранения может завершиться неудачей на полпути, что, конечно, является серьезной ошибкой приложения, но в этом случае лучше оставить старый файл, чем поврежденный наполовину записанный файл. Та же проблема возникнет, если приложение будет по какой-то другой причине завершено в середине записи файла.

Самый надежный подход, который я могу придумать, - это использовать временный файл при сохранении и заменять исходный файл только после успешного создания нового файла. Но я обнаружил, что есть несколько операций (создание временного файла, сохранение в временном файле, удаление оригинала, перемещение временного файла в исходный), которые могут или не могут завершиться неудачей, и в итоге я получаю довольно сложную путаницу операторов try / catch для их правильной обработки.

Существует ли передовая практика / стандарт для этого сценария? Например, лучше ли скопировать оригинал во временный файл и затем перезаписать оригинал, чем сохранить во временный файл?

Кроме того, как можно объяснить состояние файла в приложении на основе документов (в Windows)? Лучше оставить файл открытым для записи приложением до тех пор, пока пользователь не закроет документ, или просто быстро открыть прочитанный файл и быстро закрыть его снова? Плюсы и минусы?

Ответы [ 3 ]

1 голос
/ 20 августа 2011

Обычно танец перетасовки файлов выглядит примерно так, и в итоге получается file.txt, содержащий новые данные:

  • Запись в file.txt.new
  • Перемещение файла.txt в file.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 голосов
/ 20 августа 2011

Создание временного файла, а затем замена исходного файла временным файлом (последний является дешевой операцией с точки зрения ввода / вывода) - это механизм, используемый классами сохранения документов MFC. Я НИКОГДА не видел, чтобы это провалилось. Также пользователи не сообщали о таких проблемах. И да, тогда документы были большими (они также были сложными, но это не имеет значения, если речь идет о вводе / выводе).

0 голосов
/ 20 августа 2011

Отвечая на последний вопрос:

Если мы говорим здесь о довольно сложных и больших файлах, я бы лично решил заблокировать файл, так как во время чтения мне может не понадобиться загружать все данные на просмотр, а только то, что сейчас нужно одному пользователю.

Один первый:

  1. Всегда сохранять во временном файле.
  2. Замените старую на новую, если это не удастся, учитывая, что ваше приложение является приложением для управления документами, ваша основная цель не выполнена, поэтому наихудший случай, но у вас есть новый временный файл. Таким образом, эта ошибка может привести к закрытию приложения и повторному открытию (критическая ошибка) при повторном открытии элемента управления при наличии временного файла, если да, запустить восстановление данных, более или менее аналогично VS в случае сбоев.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...