多线程文件访问(锁定控制)

本文关键字:控制 锁定 文件 访问 多线程 | 更新日期: 2023-09-27 18:31:20

我有两个程序在同一个文件上工作我希望第一个程序定期检查文件,如果对文件进行了任何更改并清空它。另一个程序写入该文件。当第二个程序尝试写入文件时,会出现此问题,因为它是从第一个程序使用的是否有一种(如果有任何实现的 C# 程序会更好)算法来处理这个问题?

多线程文件访问(锁定控制)

要检查文件是否已更改,您可能首先检查其时间戳。在伪代码中,您可以在监视程序中尝试如下操作:

try {
  if(FileTimeStampHasChanged(FileName)) {
    //Attempt to do something with the file
  }
}
catch {
  // Handle or ignore the exception if you can't open the file (maybe the other application hasn't finished writing). You can always retry later.
}

但是,我强烈建议完全采用不同的方法。以下是我建议的选项。

  1. 如果你可以更改编写程序,让它写入一个临时文件(例如 output.$$$),让它在完成写入后立即重命名它。重命名是即时的,不会导致任何锁定。根据我的经验,这是并发访问的最佳简单解决方案之一。
  2. 如果无法更改编写程序,请修改阅读程序。使用我在第 1 点中描述的逻辑,让它尝试重命名文件以读取和处理重命名的副本。如果重命名失败,则表示编写器未完成,可以稍后进行尝试。
  3. 如果您无法更改任何程序,则可以创建自己的"交通管理员"应用程序来实现第 1 点。它需要更多的工作,但它仍然是可行的。方法如下:
    • 配置编写器以写入文件夹,例如"输出"。
    • 将读取器配置为从另一个文件夹读取,例如"输入"。
    • 编写您的交通管理员,以便它监视输出文件夹,并在文件更改时将其移动到输入文件夹。移动也是瞬时的(它实际上与重命名的操作相同)。

您正在寻找使用FileShare.Write或使用FileStream构造函数的ReadWrite在两个程序中打开文件。

如果以这种方式打开文件,则两者都可以写入。请注意,您必须在 2 个程序之间手动实现一些同步机制,以便它们不会覆盖彼此的数据。

每次写入后关闭文件并在打开时等待文件解锁可能是更容易的选择,具体取决于访问模式。

请注意,如果您无法控制其中一个程序,您唯一的选择就是简单地等待它完成程序中的文件(您可以强制其他程序关闭文件句柄,但您只是不想这样做,因为它可能会损坏数据)。