如何检查文件是否正在使用?

4

在尝试读取文件之前,有没有任何方法可以先测试文件是否正在使用中?例如,如果文件仍在被写入或被认为正在使用,则此代码块将抛出异常:

try
{
    FileStream stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read);
}
catch (IOException ex)
{
    // ex.Message == "The process cannot access the file 'XYZ' because it is being used by another process."
}

我已经查找了很多资料,最好的方法似乎是使用轮询并在其中添加try catch语句,但这种方法感觉非常不专业。我本来期望在System.IO.FileInfo中会有更好的解决方案,但实际上并没有。

你们有更好的想法吗?

2个回答

4

您可以直接通过P/Invoke层调用LockFile API函数。您将使用FileStream上的SafeFileHandle属性返回的句柄。 直接调用API将允许您检查返回值以获取错误条件,而不是借助于捕获异常。

"try/catch块是正确的解决方案(尽管您希望捕获IOException,而不是所有异常)。没有办法可以正确同步,因为测试锁定+获取锁定不是原子操作。"

"请记住,文件系统是易变的:仅因为您的文件在一次操作中处于一种状态,并不意味着它会在下一次操作中处于相同的状态。您必须能够处理来自文件系统的异常。"

使用C#是否可以测试文件上是否有锁定

http://www.dotnet247.com/247reference/msgs/32/162678.aspx


我并不太关心它是否是原子性的。那个链接谈到了通过P/Invoke进行检查的能力。我在哪里可以找到更多信息来看看它是否有所帮助? - mckamey
@McKAMEY:请查看我刚添加的第二个链接。 - cakeforcerberus
由于文件系统的更改始终是可能的,因此正确的答案是尝试并在发生异常时处理它。此外,直接请求要比跳过多个步骤以找出是否正在使用更容易。 - Loren Pechtel

0

一个尝试执行它的函数只需要在循环中使用try catch。就像处理数据库一样,找出是否可以做某事的最好方法是尝试去做它。如果失败了,就处理它。除非你的线程代码有问题,否则你的程序应该能够打开文件,除非用户已经在另一个程序中打开了它。

当然,除非你正在做一些有趣的事情。


我正在尝试做一些有趣的事情 :) 在我的特定情况下,这可能是长时间运行的锁定,并且我不想在循环中支付try-catch的代价。偶尔出现是可以接受的,但它可能比异常情况更常见。 - mckamey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接