读取文件时不会阻止其他进程同时读取它

时间:2011-06-30 18:04:16

标签: c# .net timer filesystemwatcher

我正在C#/ .NET中创建一个小应用程序来监视文件的创建,当它被创建时,它会获取其内容,解析它并将其写入另一个文件。

到目前为止一切正常。但问题是:还有另一个进程可以监视此文件。我的进程只是读取文件,而第二个文件读取它然后删除它。

我的应用程序正在完成它的工作,但是当它读取文件时,另一个进程无法读取它并完全崩溃(不是由我做的,也没有来源来修复它)。

我的应用程序运行速度非常快,其他打开文件的时间很短,无法获取内容并将其放入变量中,因此可以更快地关闭文件,然后解析变量中文件的内容。

我显然不知道如何,但我希望能够读取文件,让对方同时读取文件,没有任何打嗝。可能吗?我仍然认为在另一个应用程序完成解析之后文件被删除这个事实会有问题......

有任何建议或想法吗?

非常感谢!

5 个答案:

答案 0 :(得分:3)

您可以按如下方式打开文件,以确保不会将其与其他进程锁定:

using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
{
  // do your stuff
}

但是如果其他进程尝试以独占模式打开它,它将无济于事,它仍然会崩溃。除了修复其他进程的代码之外,没有办法解决这个问题。

答案 1 :(得分:2)

如果您使用的是NTFS驱动器(非常可能),则可以创建该文件的硬链接。从本质上讲,这会复制文件而不会实际创建副本。您可以使用硬链接读取文件。另一个进程可以删除该文件,该文件只会删除其对该文件的链接。这将使文件留在原处供您阅读。当您的程序读完文件后,它可以删除硬链接,文件系统会看到两个链接都被删除了,它将自己删除文件。

可以通过command line

来完成
fsutil hardlink create <NewFileName> <ExistingFileName>

或者您可以P/Invoke Windows API中的CreateHardLink功能。

答案 2 :(得分:2)

KISS:您是否可以在第一个程序没有查看的位置创建文件,但是您的软件是 - 当您完成处理后,您将其移动到第一个程序是看?

否则: 你将有争用,因为它将是一场比赛,看看哪个进程实际上“注意到”文件并开始工作。

我假设您对创建文件的过程也没有任何控制权?

在这种情况下,您可以查看PsSuspendPauseSp - 如果您可以通过暂停它来控制其他进程,直到您准备好它(完成文件),那么这可能是可行的。不确定这会有多强大。

还有潜在的竞争条件“注意”文件并执行操作(无论它是什么) - 保持其他进程永久暂停,直到您希望它运行(或杀死它并启动它)是唯一的在约束条件下实现你想要的确定性方法。

答案 3 :(得分:0)

你能创建另一个空的零字节文件,名为.reading文件,该文件具有相同的名称,但扩展名为“读取”。然后,一旦第一个进程完成读取文件,重命名.reading到.done,第二个进程可以检查.done文件并删除原始文件,因为.done和原始文件具有相同的名称但不同的扩展名?

答案 4 :(得分:0)

@ Prashant的回复给了我灵感,它非常相似,但我相信会解决你的问题。

如果其他进程必须匹配某个文件名模式

  • 将文件重命名为该文件 不会先匹配,非常便宜/快 操作
  • 完成后重命名

如果它匹配给定文件夹中的每个文件

  • 将其移至另一个文件夹(在大多数文件系统中也是一个非常便宜的操作)
  • 完成后将其移回。

如果其他进程已经锁定了您的文件(即使是读取),那么您的进程将失败,您可以使其优雅。如果不是,你应该是安全的。

当然,仍然存在竞争条件,但这应该比你正在做的更加安全。