我应该在追加写入之间保持文件处理程序打开吗?

Should I keep a file handler open between append writes?

我在做一个涉及数据采集的项目。一个非常重要的必要条件是这样描述的:

  1. 开始录制时,必须创建一个文件,并写入文件头;
  2. 数据采集一开始,应用程序就应定期(通常每秒一次)将采集到的数据保存到文件中;
  3. 写入包括将数据块附加到文件,如果可能的话,以原子方式;
  4. 如果发生任何错误(程序错误、电源故障),文件必须保持有效直到错误前的最后一次写入。

所以我打算用一些Thread来观察接收到的数据并将这个数据写入文件,但我不知道哪种做法最好(下面的代码不是真实的,只是为了感受):

第一个选项:单开

using (var fs = new FileStream(filename, FileMode.CreateNew, FileAccess.Write))
    fs.Write(headers, 0, headers.Length);

using (var fs = new FileStream(filename, FileMode.Append, FileAccess.Write))
{
    while (acquisitionRunning)
    {
        Thread.Sleep(100);
        if (getNewData(out _someData;))
        {                        
            fs.Write(_someData, 0, _someData.Length);
        }
    }
}

第二个选项:多次打开:

using (var fs = new FileStream(filename, FileMode.CreateNew, FileAccess.Write))
    fs.Write(headers, 0, headers.Length);

while (acquisitionRunning)
{
    Thread.Sleep(100);
    if (getNewData(out _someData;))
    { 
        using (var fs = new FileStream(filename, FileMode.Append, FileAccess.Write))
        {                       
            fs.Write(_someData, 0, _someData.Length);
        }
    }
}

应用程序应该在客户端机器上运行,其他进程的文件访问应该不是问题。我最关心的是:

  1. 多次 open/close 影响性能(注意典型的写入间隔是每秒一次);
  2. 万一发生故障(包括明确断电),哪一个最能保证文件完整性安全?
  3. 这些表格中的任何一种被认为是特别好的或不好的做法,或者可以根据手头问题的具体情况使用其中任何一种?

正如您所提到的,其他进程不会访问该文件,因此将其保持打开状态不会使事情复杂化,而且速度会更快。但是,请记住,如果应用程序崩溃,锁将保留在文件上,您可能需要根据您的情况进行相应处理。

在断电 outage/etc 时保留文件内容的一个好方法是在每次写入后刷新文件流。这将确保您刚刚写入流的内容立即写入磁盘。