File.WriteAllText не сбрасывает данные на диск
У меня было 3 сообщения о сбоях компьютеров пользователей во время использования моего программного обеспечения ... сбои не связаны с моей программой, но при перезапуске конфигурационных файлов моя программа пишет, что все повреждено.
Нет ничего особенного в том, как записываются файлы, просто создайте представление Json и выгрузите его на диск с помощью File.WriteAllText ()
// save our contents to the disk
string json = JsonConvert.SerializeObject(objectInfo, Formatting.Indented);
// write the contents
File.WriteAllText(path, json);
У меня был пользователь, отправивший мне один из файлов, и длина выглядит примерно правильно (~ 3 КБ), но все содержимое - 0x00.
Согласно сообщению ниже File.WriteAllText должен закрыть дескриптор файла, сбросив все неписанное содержимое на диск:
В моем коде C # компьютер ждет завершения вывода, прежде чем двигаться дальше?
НО, как отметил Альберто в комментариях:
System.IO.File.WriteAllText после завершения сбрасывает весь текст в кэш файловой системы, затем он будет лениво записываться на диск.
Итак, я предполагаю, что здесь происходит то, что файл очищается и инициализируется с 0x00, но данные еще не записаны при сбое системы.
Я думал о том, чтобы использовать какой-то временный файл, поэтому процесс будет выглядеть так:
Записать новое содержимое во временный файлУдалить оригинальный файлПереименовать временный файл в исходныйЯ не думаю, что это решит проблему, так как я предполагаю, что Windows просто переместит файл, даже если ввод-вывод еще не завершен.
Можно ли каким-то образом заставить машину выгружать эти данные на диск, а не решать, когда это делать, или, возможно, лучший способ обновить файл?
ОБНОВИТЬ:
Основываясь на предложениях @usr, @mikez и @llya luzyanin, я создал новую функцию WriteAllText, которая выполняет запись, используя следующую логику:
Создайте временный файл с новым содержимым, используя флаг FileOptions.WriteThroughЗаписывает данные на диск (не вернется, пока запись не завершится)File.Replace для копирования содержимого нового временного файла в реальный файл, делая резервную копиюС этой логикой, если не удается загрузить окончательный файл, мой код проверяет наличие файла резервной копии и загружает его вместо
Вот код:
public static void WriteAllTextWithBackup(string path, string contents)
{
// generate a temp filename
var tempPath = Path.GetTempFileName();
// create the backup name
var backup = path + ".backup";
// delete any existing backups
if (File.Exists(backup))
File.Delete(backup);
// get the bytes
var data = Encoding.UTF8.GetBytes(contents);
// write the data to a temp file
using (var tempFile = File.Create(tempPath, 4096, FileOptions.WriteThrough))
tempFile.Write(data, 0, data.Length);
// replace the contents
File.Replace(tempPath, path, backup);
}