7

好的,所以解释一下;我正在开发一个可能在任何时间点出现电源故障的系统,我正在测试的一点是在我使用 StreamWriter 写出文件之后直接进行的。下面的代码:

// Write the updated file back out to the Shell directory.
using (StreamWriter shellConfigWriter =
        new StreamWriter(@"D:\xxx\Shell\Config\Game.cfg.bak"))
{
    for (int i = 0; i < configContents.Count; i++)
    {
        shellConfigWriter.WriteLine(configContents[i]);
    }
    shellConfigWriter.Close();
}

FileInfo gameCfgBackup = new FileInfo(@"D:\xxx\Shell\Config\Game.cfg.bak");
gameCfgBackup.CopyTo(@"D:\xxx\Shell\Config\Game.cfg", true);

shellConfigWriter将(a of strings)的内容写入List用作临时存储的文件,然后将其复制到原始文件上。现在,在此代码完成执行后,电源丢失,再次启动备份时,文件Game.cfg存在并且大小正确,但完全空白。起初我认为这是由于在硬盘驱动器上启用了写入缓存,但即使关闭它仍然会发生(尽管不太常见)。

任何想法都会非常受欢迎!

更新:好的,所以在删除.Close()语句并在每次写入操作后调用.Flush()后,文件仍然是空白的。我可以更进一步,在创建新文件之前先创建原始文件的备份,然后我有足够的备份来进行完整性检查,但我认为这无助于解决根本问题(当我告诉它写入时,刷新并关闭文件......它没有!)。

4

3 回答 3

14

防止操作系统使用对象构造函数的FileOptions参数缓冲输出:FileStream

    using (Stream fs = new FileStream(@"D:\xxx\Shell\Config\Game.cfg.bak", FileMode.Create, FileAccess.Write, FileShare.None, 0x1000, FileOptions.WriteThrough))
    using (StreamWriter shellConfigWriter = new StreamWriter(fs))
    {
        for (int i = 0; i < configContents.Count; i++)
        {
            shellConfigWriter.WriteLine(configContents[i]);
        }
        shellConfigWriter.Flush();
        shellConfigWriter.BaseStream.Flush();
    }
于 2009-09-15T15:14:26.743 回答
7

首先,你不必在shellConfigWriter.Close()那里打电话。该using声明将处理它。为了防止电源故障,您可能想要做的是 call shellConfigWriter.Flush()


更新
您可能要考虑的其他事情是,如果电源故障确实可能在任何时候发生,它可能发生在写入过程中,这样只有一些字节才能写入文件。真的没有办法阻止它。

为了防止这些情况,一个常见的过程是使用状态/条件标志文件。您可以使用具有特定名称的零字节文件在文件系统上的存在或不存在来告诉您的程序在恢复时从哪里重新拾取。然后,在您确定您已达到该状态并完成前 一个状态之前,您不会创建或销毁触发特定状态的文件。

这里的缺点是它可能意味着不时地丢掉很多工作。但好处是它意味着代码的功能部分看起来很正常:只需要做很少的额外工作即可使系统足够健壮。

于 2009-09-15T13:51:23.637 回答
0

你想设置AutoFlush = true;

于 2009-09-15T14:36:23.517 回答