【问题标题】:Can I use FileStream to implement a file lock?我可以使用 FileStream 来实现文件锁定吗?
【发布时间】:2010-11-29 17:59:58
【问题描述】:

我可以使用FileStream 构造函数来确保一次只有一个进程访问一个文件吗?下面的代码会起作用吗?

public static IDisposable AcquireFileLock() {
    IDisposable lockObj;
    do {
        // spinlock - continually try to open the file until we succeed
        lockObj = TryOpenLockFile();

        // sleep for a little bit to let someone else have a go if we fail
        if (lockObj == null) Thread.Sleep(100); 
    }
    while (lockObj == null);

    return lockObj;
}

private static FileStream TryOpenLockFile() {
    try {
        return new FileStream(s_LockFileName, FileMode.Create, FileAccess.Read, FileShare.None);
    }
    catch (IOException) {
        return null;
    }
}

特别是FileMode.Create atomic WRT 其他进程的行为?还有什么我应该使用的吗?

编辑:更具体地说,这是在 Microsoft CLR 上使用单台计算机上的本地文件。

【问题讨论】:

  • 这看起来不错!谁清理了锁定文件?可能没有功能需要这样做,因为FileStream ctor 调用总是覆盖现有的锁定文件。
  • 为了清理,我总是可以try { File.Delete(...) } 并忽略任何异常(因为这意味着另一个进程同时已获得锁定)...

标签: .net filestream file-locking


【解决方案1】:

这会做你想做的事。 FileShare.None 是重要的部分。

如果所有编写器应用程序都在同一台计算机上,您还可以使用named Mutex 来实现相同的目标而无需物理文件,或者如果您不关心谁写入文件,则可以调解文件访问最后(只是写入不是并发的)。这可以使您不必每次都重新打开文件,并提供阻塞语义而不是 Sleep 循环(更好的性能)。

请注意,如果名称不被视为机密,即需要保密的信息,任何进程都可以占用您的文件 (Mutex)。

【讨论】:

  • 互斥锁只能在同一台计算机上工作。文件锁可以跨网络工作。
  • @Gabe - 不清楚用例是什么,但你是对的
【解决方案2】:

考虑到以下注意事项,这将起作用:

  • 您在 Windows 上(通过 Mono 在 Linux 上,这不成立,因为文件锁定是建议性的,所以您的方法总是成功)
  • 您正在访问一个本地文件(SMB 也可能工作,但 NFS 或 WebDAV 几乎肯定不会)
  • 捕获 IOException 可能过于宽泛,您需要专门验证它是否因共享冲突而失败

【讨论】:

  • IOException 是文件已被锁定时抛出的异常,我无法捕捉到更具体的内容:/
  • 您可以检查 HResult 以查看它是否有 Win32 错误代码,否则,您可以(呃)检查消息文本
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
  • 2021-07-09
相关资源
最近更新 更多