Может записать в файл сбой в середине операции сброса

Я пишу содержимое в CSV-файл по одной строке за раз и задавался вопросом, может ли запись потерпеть неудачу в середине операции сброса

Моя цель — понять, как повредить запись в файл.

Предположим, что ниже приведена структура CSV-файла после успешной записи в него

 1,1001210212
2,8941321654
6,845646
17,564968896

Скажем, ошибка происходит при сбросе 3-й строки в файл, это может привести к следующей форме

 1,1001210212\n       //showing \n just for understanding purpose. Not actually visible as "\n" in the file
2,8941321654\n
6,845

Или же

 1,1001210212\n
2,8941321654\n

или же

1,1001210212\n
2,8941321654\n
6,845646\n              //Fails right after writing the line. Not sure if such an error is even possible

или же

1,1001210212\n
2,8941321654\n
6,845646

Мой код при необходимости

something.cpp

hash_map<int, unsigned long long> tableData;

//assume hash map is populated here

string outFile = "C:\outFile.csv";
FILE *fout = NULL;

if (outFile.length())
{
fout = fopen(outFile.c_str(), "a");
}
if (fout != NULL)
{
for (vector<uint32_t>::iterator keyValue = keys.begin();
keyValue != keys.end(); ++keyValue)
{
fprintf(fout,"%d,",*keyValue);
fprintf(fout,"%lld\n",tableData[*keyValue]);
fflush(fout);
}
}

0

Решение

Стандарт C имеет следующее, чтобы сказать о fflush функция:

Если stream указывает на выходной поток или поток обновления, в котором самые последние
операция не была введена, fflush Функция вызывает любые неписанные данные для этого потока
быть доставленным в среду хоста для записи в файл; в противном случае поведение
не определено.

Обратите внимание на осторожную формулировку: данные доставлено в хост-среду. То, что делает с этим среда хоста, выходит за рамки стандарта C.

fflush функция может потерпеть неудачу. В этом случае он возвращает ненулевое значение. Что в действительности происходит с файлом в случае сбоя операции очистки, определяется операционной системой, а не языком программирования C.

C тесно интегрирован с POSIX. В системе POSIX, fflush может вызвать write, POSIX говорит,

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

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

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

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

Если вы работаете в Windows, я понятия не имею, какая гарантия предоставляется.

3

Другие решения


По вопросам рекламы [email protected]