2014-05-08 28 views
0

我嘗試使用下面的代碼該進程無法訪問文件「路徑」,因爲它正被另一個進程使用

using (System.IO.StreamReader rd = new System.IO.StreamReader(path)) 
{ 
    using (System.IO.StreamWriter wr = new System.IO.StreamWriter(path)) 
    { 
     string line = null; 
     while ((line = rd.ReadLine()) != null) 
     { 
      if (String.Compare(line, active_user) == 0) 
      { 
       //do nothing 
      } 
      else 
      { 
       wr.WriteLine(active_user); 
      } 

     } 
    }          
} 

即使我用讀在C#應用程序中的文本文件中寫入一次性物品,仍然向我拋出錯誤

該進程無法訪問文件'路徑',因爲它正在被另一個進程使用。

我在哪裏出錯了?

+0

我正在檢查一切,但沒有找到任何使用該文件的應用程序。有沒有辦法強制所有進程以編程方式釋放文件? – DoIt

+0

您正在同時閱讀和寫入文件。 – tnw

+0

這是錯誤的方法。寫入一個新的臨時文件,然後刪除舊的並將新名稱重命名爲舊名稱。 –

回答

1

您正在讀取和寫入文件的同時。嘗試製作你需要編寫的字符串列表,然後在完成閱讀後寫下它們。

事情是這樣的:

List<string> toWrite = new List<string>(); 

using (System.IO.StreamReader rd = new System.IO.StreamReader(path)) 
{ 
    string line = null; 
    while ((line = rd.ReadLine()) != null) 
    { 
     if (String.Compare(line, active_user) != 0) //simplified your logic 
     { 
      toWrite.Add(active_user); 
     } 

    } 

} 
File.WriteAllLines(path, toWrite); 
2

您正在從文件中讀取變量path中定義的路徑,同時嘗試同時寫入該文件。

+1

感到驚訝,在閱讀時我無法寫入文件嗎? – DoIt

+3

要添加到此答案,您可以同時使用StreamReader和StreamWriter,但必須使用同一個流。在構造函數中使用路徑字符串意味着正在爲每個內部流創建一個單獨的內部流。首先創建您的流,然後在您的讀者/寫者構造函數中使用它。 –

+0

@NathanA解決它的最佳方法是? – DoIt

0

雖然寫作,讀者仍然在範圍和訪問文件,這就是你收到此錯誤的原因。

+0

問題不在於讀者。問題是讀者已經以阻塞模式打開文件,這是不必要的。 –

0

儘管有其他文章,但從一個文件中讀取並「同時」寫入文件沒有任何問題。理解問題的關鍵是打開文件時使用的模式。

看看你的代碼更明確的變體:

 using (FileStream fileStream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) 
     { 
      using (StreamReader rd = new StreamReader(fileStream)) 
      { 
       using (StreamWriter wr = new StreamWriter(fileStream)) 
       { 
        string line = null; 
        while ((line = rd.ReadLine()) != null) 
        { 
         if (String.Compare(line, active_user) == 0) 
         { 
          //do nothing 
         } 
         else 
         { 
          wr.WriteLine(active_user); 
          //If you flush what you write then you will see it via the reader. 
          //Comment out for better performance. Keep in mind, that writing 
          //into a file will lead to occasional flush which affects the 
          //reader. Implicit Flush happens once you write more than the 
          //buffer of the writer suggests. 
          wr.Flush(); 
         } 

        } 
       } 
      }     
     } 

正如你所看到的,它是從文件被打開的方式你的代碼不同。我只是希望明確指定我打開文件的模式。 似乎StreamReader在沒有「共享」的情況下隱式打開文件,即不允許其他人打開它,這是可以的,因爲它希望保護您免受意外結果的侵害。因此,這種隱式方法不適合你稍微「複雜」的場景。明確打開文件的竅門。 請注意,File.Open允許您打開文件並仍允許其他線程(其他應用程序)打開文件。全取決於你。

現在到你的代碼的邏輯。 StreamReader從頭開始讀取流。 StreamWriters會顯示流內容的結尾。都保持和維護自己的流位置。因此,代碼將爲文件的每行不包含「active_user」的行添加一行包含「active_user」的行。我無法想象這是一個實際的原因。

0

在讀取和寫入同一個文件時,不要在兩個不同的實例中打開它。

...喜歡打開車門讓兩個人進入。 您只能打開一次 - 您需要關閉才能打開它。 但是,你可以把它開在這兩個獲得

在下面的例子: 您打開流(一次) 然後你讓作家和讀者有機會獲得開放的單個實例文件。 當它們都完成後,您可以關閉文件。

注意:在像多線程這樣更復雜的場景中,您需要實現線程安全性,以防止讀寫器同時嘗試讀取和寫入數據。 ...但對於您的示例,下面的內容應該足夠了。

 using (System.IO.Stream stream = System.IO.File.Open(path, System.IO.FileMode.Open)) 
     { 
      using (System.IO.StreamReader rd = new System.IO.StreamReader(stream)) 
      { 
       using (System.IO.StreamWriter wr = new System.IO.StreamWriter(stream)) 
       { 
        string line = null; 
        while ((line = rd.ReadLine()) != null) 
        { 
         if (String.Compare(line, active_user) == 0) 
         { 
          //do nothing 
         } 
         else 
         { 
          wr.WriteLine(active_user); 
         } 
        } 
       } 
      } 
     } 
相關問題