Правильный выбор объектов файлового потока - PullRequest
1 голос
/ 21 июня 2011

Приложение использует RapidXML для редактирования файла XML. Редактирование не автоматизировано и происходит время от времени: содержимое XML отображается в графическом интерфейсе, и пользователь выполняет некоторые действия, которые изменяют XML. Каждое изменение должно быть немедленно сохранено на диск.

Загрузка объекта документа RapidXML требует копирования содержимого файла в строку. Каждое изменение в документе сопровождается копированием содержимого объекта документа обратно в файл.

Файл используется для ввода и вывода в этом примере. Должен ли один std::fstream объект использоваться для всех операций ввода / вывода в этом случае? Он будет открыт один раз при запуске приложения, использован для ввода / вывода и закрыт в конце приложения.

Или, локальные (временные) экземпляры std::ifstream и std::ofstream должны использоваться всякий раз, когда требуется выполнить ввод / вывод файла? Например. std::ifstream для использования в начале для чтения файла (открыть, прочитать, закрыть); аналогично, std::ofstream экземпляр, который будет использоваться всякий раз, когда DOM необходимо экспортировать в файл (открыть, записать, закрыть).

Я не беспокоюсь о производительности здесь (из-за характера приложения), но мне любопытно по поводу правильного выбора объектов файлового потока в этом случае.

Ответы [ 2 ]

3 голосов
/ 21 июня 2011

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

Кроме того, существуют дополнительные ограничения. Если вам требуется, чтобы данные были записаны на диск перед продолжением, вы можете использовать один std::fstream для нескольких изменений. Операционные системы обычно не сбрасывают файл на диск, даже если вы вызываете метод flush() в файловых потоках. Некоторые платформы предлагают непереносимые решения, чтобы действительно заставить запись. Поэтому, если вам нужно записать его на диск, лучше всего закрыть файл.

Таким образом, особенно для критических приложений, я бы рекомендовал второй подход (ifstream при начальной загрузке, ofstream при каждой записи). Я бы также порекомендовал записать во временный файл, а затем переместить всю перезапись в нужное место, заменив исходные файлы. Это гарантирует, что вы не потеряете данные (по крайней мере, в системах, предлагающих атомарное перемещение файлов).

2 голосов
/ 21 июня 2011

Я бы определенно предпочел локальные временные экземпляры std::ifstream и std::ofstream.Я даже не уверен, что это сработало бы иначе;открытие std::ofstream очищает содержимое существующего файла.Просто поиск в начале и перезапись не удаляют предыдущее содержимое, и если результаты изменений укорачивают файл, у вас все равно останутся оставшиеся символы из предыдущего содержимого.

...