2010-09-17 56 views
9

我有一個程序,大致做到這一點:文件正被另一個進程使用

  1. 打開一個文件,從中讀取數據。
  2. 關閉文件
  3. 啓動filewatcher以監視文件中的更改。
  4. 一旦檢測到改變,則filewatcher的EnableRaisingEvents標誌被設置爲假,並且處理從步驟重複1.

的問題是,從步驟4將步驟1之後,它不能讀取文件說它正在被另一個進程使用。

錯誤我接收:

未處理的異常信息:System.IO.IOException:過程不能訪問該文件「C:\的test.xml」,因爲它正被另一個進程。

怎麼回事?我的程序的步驟1中的讀者是否仍然打開文件,或者是訪問該文件的一些完全不同的進程,還是文件觀察者在從第4步移至第1步後仍在觀察文件,儘管將標誌設置爲false?

+0

您可以發佈您的代碼。這可以幫助我們回答你的問題。 – klabranche 2010-09-17 17:10:09

+1

發佈一些代碼。幫助我們幫助你。 – 2010-09-17 17:10:37

+1

該代碼有點巨大和保密,因爲它是針對財務公司的,但是我會看看我是否可以使其安全併發布。 – xbonez 2010-09-17 17:11:07

回答

8

如果你的代碼是與此類似:

[STAThread] 
static void Main(string[] args) 
{ 
    string file = "temp.txt"; 
    ReadFile(file); 
    FileSystemWatcher fswatcher = new FileSystemWatcher(".\\"); 
    fswatcher.Changed += delegate(object sender, FileSystemEventArgs e) 
          { 
           ReadFile(e.FullPath); 
          }; 
    while (true) 
    { 
     fswatcher.WaitForChanged(WatcherChangeTypes.Changed); 
    } 
} 
private static void ReadFile(string file) 
{ 
    Stream stream = File.OpenRead(file); 
    StreamReader streamReader = new StreamReader(stream); 
    string str = streamReader.ReadToEnd(); 
    MessageBox.Show(str); 
    streamReader.Close(); 
    stream.Close(); 
} 

如果您正在編輯通過記事本的文件,然後,當你點擊保存按鈕,它保持打開文件,而當你剛剛關閉程序並點擊保存沒有。我不知道這是一個錯誤還是記事本的一個未記錄的功能,但這可能是您的問題。解決此問題的一種方法是執行以下操作:

在您的匿名代理或您執行ReadFile()調用的任何地方調用Thread.Sleep(1000),讓程序在讀取文件之前等待並且您的代碼應該正常工作。

+1

Thread.Sleep似乎已經解決了這個問題。謝謝! – xbonez 2010-09-17 17:57:52

+0

@xbonez:即使沒有'Thread.Sleep()',這段代碼對我來說也很好。 (我把'MessageBox.Show'改成了'Console.WriteLine')但是,我仍然會使用'using'語句。 – JohnB 2010-09-17 18:06:27

+0

在玩了更多之後,我發現如果我有兩個這個程序的實例看着同一個文件,當我在記事本中單擊「保存」時,我從其中一個實例中得到這個錯誤(另一個繼續運行): '進程無法訪問'c:\ file.txt'文件,因爲它正被另一個進程使用。' – JohnB 2010-09-17 18:44:24

4

您可以使用諸如Process Explorer的工具從http://www.sysinternals.com,看看誰具有開門把手的過程

該文件很可能是持有開放任何導致改變通知首先開火。

+0

+1進程管理器。 – NotMe 2010-09-17 17:11:45

0

有很多事情可以繼續下去。

首先,確保你正確處置文件寫入器(關閉不夠好),通過利用使用條款圍繞實施IDisposable的一切。

其次,它只是簡單地閱讀,確保打開文件時設置了正確的標誌。

如果你提供了一個代碼塊來展示你如何完成這個任務,特別是在讀取文件的周圍時

+0

+1:我同意,使用'using'語句 – JohnB 2010-09-17 17:34:36

3

注意:即使在記事本中打開了「file.txt」,此代碼仍然有效,因爲它正在打開供讀取。

using System; 
using System.IO; 

class Program 
{ 
    static void Main(string[] args) 
    { 
    ReadFromFile(@"C:\file.txt"); 
    Console.ReadLine(); 
    } 

    static void ReadFromFile(string filename) 
    { 
    string line; 
    using (StreamReader sr = File.OpenText(filename)) 
    { 
     line = sr.ReadLine(); 
     while (line != null) 
     { 
     Console.WriteLine(str); 
     line = sr.ReadLine(); 
     } 
     sr.Close(); 
    } 
    } 
} 

或者只是:

string text = System.IO.File.ReadAllText(@"C:\file.txt");

3

除了其他答案,有可能當FileWatcher反應文件,它尚未關閉該應用程序。在第1步中儘量不要立即失敗,而要嘗試幾次延遲較小的嘗試。

0

您可以使用此MS實用程序openfiles獲取已打開文件的列表並瞭解誰已打開文件。

openfiles /query 

此外,它允許斷開網絡用戶打開的文件。

openfiles /disconnect /id XXXX 

如果你想使用它的本地PC,你應該設置維護對象列表全局標誌:

openfiles /local on 

按照link以獲得更多的細節。

相關問題