2010-06-07 289 views
16

有没有办法找到文件是否已经打开?检查文件是否打开

+2

请提供更多细节。已经由您的流程或其他流程打开?打开期间,还是刚刚打开写权限?怎么分享?等等。这个问题太模糊了。 – hemp 2010-06-07 07:11:34

回答

26
protected virtual bool IsFileinUse(FileInfo file) 
{ 
    FileStream stream = null; 

    try 
    { 
     stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); 
    } 
    catch (IOException) 
    { 
     //the file is unavailable because it is: 
     //still being written to 
     //or being processed by another thread 
     //or does not exist (has already been processed) 
     return true; 
    } 
    finally 
    { 
     if (stream != null) 
     stream.Close(); 
    } 
    return false; 
} 
+2

如果进程没有对文件的写入访问权限,则会产生误导性结果(打开将失败,但不一定是因为存在句柄)。打开Read访问将不太容易出错。 – hemp 2010-06-07 07:08:53

+4

令人惊讶的是,大多数语言没有测试文件的方法。我们以前在OS/2中使用C++下的相同类型的方法。即尝试打开文件专用。它工作得不错,但我从来没有想过它优雅。 – Matt 2010-06-07 07:34:30

+2

这不是一种语言功能,它是一项操作系统功能。那里只是不存在一个简单的API(在Windows中)来查询这些信息。有可能得到,但是它是低级别的,并且有很多参数需要被指定来知道“open”是什么意思。 – hemp 2010-06-07 08:07:16

7

正如蛙@pranay,但我们需要确保我们关闭我们的文件句柄:

public bool IsFileInUse(string path) 
{ 
    if (string.IsNullOrEmpty(path)) 
    throw new ArgumentException("'path' cannot be null or empty.", "path"); 

    try { 
    using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read)) { } 
    } catch (IOException) { 
    return true; 
    } 

    return false; 
} 
+0

同@pranay rana,我测试了这种方法,但它不检测文件在记事本中何时打开。 – James 2016-10-19 12:42:19

1

如果你的意思是你要检查文件是否打开您尝试打开它之前, 那就不要。 (至少不是没有进入低级别,并检查系统中打开的每个文件句柄。)

此外,当你得到它时,信息会变老。即使测试会返回该文件未打开,在您有机会使用返回值之前它可能已经打开。

因此,处理这种情况的正确方法是尝试打开文件,并处理可能发生的错误。

0

同意。我会创建一个指定的类,它包装了打开的文件逻辑或至少是测试(IsFileAvailable)。这将允许您将异常管理与专门负责的类相关联,并使其可重用。你甚至可以应用更多的逻辑,例如测试文件大小以查看文件是否正在写入等等,以提供更详细的响应。它也将使你的消费代码更清洁。