2010-06-07 250 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)。這將允許您將異常管理與專門負責的類相關聯,並使其可重用。你甚至可以應用更多的邏輯,例如測試文件大小以查看文件是否正在寫入等等,以提供更詳細的響應。它也將使你的消費代碼更清潔。