gpt4 book ai didi

c# - File.WriteAllText 不将数据刷新到磁盘

转载 作者:可可西里 更新时间:2023-11-01 12:41:32 29 4
gpt4 key购买 nike

我现在收到 3 份用户机器在使用我的软件时崩溃的报告。崩溃与我的程序无关,但当他们重新启动配置文件时,我的程序写入的所有文件都已损坏。

文件的写入方式没有什么特别之处,只需创建一个 Json 表示并使用 File.WriteAllText() 将其转储到磁盘

// save our contents to the disk
string json = JsonConvert.SerializeObject(objectInfo, Formatting.Indented);

// write the contents
File.WriteAllText(path, json);

我有一位用户向我发送了其中一个文件,长度看起来是正确的 (~3kb),但内容都是 0x00。

根据下面的帖子,File.WriteAllText 应该关闭文件句柄,将所有未写入的内容刷新到磁盘:

In my C# code does the computer wait until output is complete before moving on?

但是,正如 Alberto 在评论中指出的那样:

System.IO.File.WriteAllText when completes, will flush all the text to the filesystem cache, then, it will be lazily written to the drive.

所以我假设这里发生的是文件正在被清除并用 0x00 初始化,但是当系统崩溃时数据还没有写入。

我正在考虑使用某种临时文件,所以过程是这样的:

  1. 将新内容写入临时文件
  2. 删除原文件
  3. 将临时文件重命名为原始文件

我认为这不会解决问题,因为我认为即使 IO 仍未决,Windows 也会移动文件。

有什么方法可以强制机器将该数据转储到磁盘,而不是由它决定何时执行此操作或更新文件的更好方法?

更新:

根据@usr、@mikez 和@llya luzyanin 的建议,我创建了一个新的 WriteAllText 函数,它使用以下逻辑执行写入:

  1. 使用 FileOptions.WriteThrough 标志创建一个包含新内容的临时文件
  2. 将数据写入磁盘(写入完成后才会返回)
  3. 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);
}

最佳答案

您可以使用 FileStream.Flush 将数据强制写入磁盘。写入临时文件并使用 File.Replace 自动替换目标文件。

我相信这一定会奏效。文件系统提供弱保证。这些保证几乎没有记录,而且很复杂。

或者,如果可用,您可以使用事务性 NTFS。它可用于 .NET。

FileOptions.WriteThrough 可以替代 Flush,但如果您的数据超过单个簇的大小,您仍然需要临时文件。

关于c# - File.WriteAllText 不将数据刷新到磁盘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25366534/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com