Безопасный способ записи файла конфигурации в C - PullRequest
1 голос
/ 23 марта 2020

Я обнаружил проблему, когда один процесс обновляет конфигурацию. Иногда файл конфигурации будет пустым. Я проанализировал журнал; есть журнал после открытия, но не журнал до fwrite.

Так что я пришел к выводу, что если процесс падает после fopen, но перед записью, происходят плохие вещи. Я знаю, что fwrite (w) сначала очистит файл, а затем добавит содержимое в файл, поэтому полное дисковое пространство и процесс cra sh могут вызвать проблемы.

Мне интересно, есть ли безопасный способ? обновить файл конфигурации в C (лучше использовать C ++ 98 при использовании C ++; у нас очень старый проект, который не поддерживает C ++ 11, 14…).

Вот Простой пример, который я написал. Когда в file.txt есть что-то, раскомментируйте возвращаемый 0, тогда file.txt будет пустым.

#include<stdio.h>

int main () {
   FILE *fp;
   char str[] = "This is stackoverflow.com";

   fp = fopen( "file.txt" , "w" );
   //print log after fopen
   //if the process killed or exit here,file will be empty
   //return 0;

   //print log before fwrite
   fwrite(str , 1 , sizeof(str) , fp );
   //print log after fwrite
   fclose(fp);

   return(0);

}

Ответы [ 2 ]

1 голос
/ 23 марта 2020

fwrite() буферизируется. То, что вы пишете, хранится в памяти в стандартных буферах ввода / вывода.

Это действительно означает, что данные могут быть потеряны в случае сбоя программы (вскоре после вызова записи).

При вызове fflush(), буферы ввода / вывода сбрасываются в ОС. В этом случае ОС несет ответственность за то, чтобы данные оказались на диске. Когда происходит сбой приложения после вызова fflush(), данные, как правило, по-прежнему записываются на диск.

Подробнее см. в этом вопросе .

Как @ Eugine Sh. Правильные комментарии выше: Вы должны проверить результат каждого из этих C вызовов библиотеки.

Чтобы избежать немедленной очистки ранее существующего файла конфигурации, вы можете использовать библиотечную функцию tmpfile() C для создания временная новая версия. Затем, когда это будет сделано, вы можете скопировать содержимое в окончательный файл конфигурации. Конечно, вы также можете кэшировать данные конфигурации в буфере памяти.

РЕДАКТИРОВАТЬ: В зависимости от вашей ОС, посмотрите, что вы можете сделать с блокировками файлов.

0 голосов
/ 25 марта 2020

Вы можете открыть его с помощью fopen(a), который добавляет содержимое в файл, а затем rewind или fseek в первую позицию файла.

Но, возможно, это решение будет хуже, если вы Напишите меньше, чем предыдущее содержимое файла, потому что тогда они будут смешаны: первые байты будут записаны, но после этого вы найдете предыдущее содержимое. Вы можете truncate файл, но тогда точка отказа просто в другом месте.

Правильное решение - создать другой временный файл и заменить (переопределить) исходный файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...