不确定 C#.NET 中的文件锁定机制

Uncertain about file-locking mechanism in C#.NET

在我的测试环境中,我有两个 Windows 7 个物理客户端。两者都可以访问托管在 Windows 服务器系统上的网络共享。

客户端,分别是运行可能会尝试同时操作(读或写)同一个文本文件的应用程序。

我想用FileInfo.Open()的方式来实现不同的场景:

场景一:应用允许同时阅读。如果另一个实例实际上正在写入它,它应该会失败。

我会用

FileInfo fi = new FileInfo(filePath);
using (FileStream fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
{
    // Do some read operations...
    Console.WriteLine("Press ENTER to close file-stream...");
    Console.ReadLine();
}

为此。

场景2:尝试写入文件时,只允许一个实例打开文件。如果任何其他实例正在读取它,它应该会失败。

我会用

FileInfo fi = new FileInfo(filePath);
using (FileStream fs = fi.Open(FileMode.Open, FileAccess.Write, FileShare.None))
{
    // Do some write operations...
    Console.WriteLine("Press ENTER to close file-stream...");
    Console.ReadLine();
}

为此。


使用上面的代码片段,我的场景按预期工作。即使我在 using(...) 语句中关闭了一个实例,文件也会得到 "unlocked".

Q1: 我在考虑是否会在应用程序崩溃时发生任何事情,以便其他实例访问该文件将被拒绝(有几次?)。

Q2:打开文件时网络连接断开会怎样?

问题 3: 是否有任何理由(另外)使用 FileStream.Lock() and Unlock() 方法显式锁定和解锁文件?

Q4: 服务器的系统是否需要任何东西来实现这种文件锁定方式 运行ning?

Q5:还有什么我需要考虑的地方吗?

您所指的文件锁定是在 OS 级别完成的。因此,如果您的应用程序崩溃、出错等,它会释放该文件。这适用于 Q1 和 Q2(尽管 Q2 取决于网络拓扑和后备存储)。当心锁定文件可能会导致启用缓冲的后备存储出现奇怪的性能问题。 Q3、Lock、Unlock指的不是文件锁,而是文件内的字节。这是一个完全不同的概念,它会导致您在 NAS 类型存储上出现奇怪的行为 Q4,正如我之前所说,它是一个 OS 级别的概念。 Q5.考虑一种更好的管理方式,使用文件是一个相对较旧的概念,但是,恕我直言,在网络上的多台计算机之间共享文件是一种奇怪的令人头疼的行为。现代文件存储不适合这个概念,缓冲、延迟和安全性使其变得具有挑战性。尽可能避免它。如果做不到这一点,请确保优化您的应用程序,使其尽快打开文件、写入、关闭和刷新流。

... could anything happen on an application crash

不是特别的,当OS清理弹片并关闭应用程序未关闭的任何文件时,锁会立即释放。

What happens on loosing network connection while a file is opened?

您将得到一个运行时异常,IOException。只能通过恢复网络连接并重新打开文件来恢复。网络通常足够可靠,可以考虑不自动执行此操作,YMMV。

Are there any reasons to (additionally) use the FileStream.Lock() ...

没有。这些函数锁定文件 data 而不是文件访问。数据库引擎会做的事情。它永远不会应用于文本文件,因为它们是流,而且您永远不知道文件中一行文本的确切文件位置。

Does the servers' system require anything ...

不,这是操作系统内置的。

Are there additional points I have to think about?

您可能应该考虑更多关于写入文件的问题,必须有人来做。使用 FileShare.None 很简单,但在文本文件上往往有点粗糙,尤其是当它们是始终保持打开状态的日志文件时。从技术上讲,应用程序可以读取正在写入的文件。往往结果很好,因为文本文件只会被附加到。您将在写入文件的应用程序中使用 FileShare.Read,并在读取文件的应用程序中使用 FileShare.ReadWrite。不是错字。