2009-10-22 8 views
17

StreamReader blokuje plik tekstowy podczas jego odczytu.
Czy mogę zmusić StreamReader do pracy w trybie "tylko do odczytu" lub "bez blokowania"?Czy mogę zapobiec blokowaniu pliku tekstowego przez StreamReader, gdy jest on używany?

Moje obejście polegałoby na skopiowaniu pliku do lokalizacji tymczasowej i przeczytaniu go z tego miejsca, ale wolałbym bezpośrednio użyć StreamReader, jeśli to możliwe. Jakieś alternatywne sugestie?

Tło:
Napisałem małą aplikację, aby pobrać statystyki z pliku dziennika. Ten plik jest ciągle aktualizowany (kilka razy na sekundę) przez program zewnętrzny umożliwiający wywołanie AAXXYY.

Przeglądanie wyników sugeruje, że moja aplikacja może blokować plik i uniemożliwić pisanie AAXXYY.

To co robię

private void btnGetStats_Click(object sender, EventArgs e) 
    { 
     int countStarts = 0; 
     int countEnds = 0; 

     IList<string> sessions = new List<string>(); 

     using(StreamReader stRead = new StreamReader(openFileDialog1.FileName,Encoding.Unicode)) 
     { 
      while(!stRead.EndOfStream) 
      { 
       string line = stRead.ReadLine(); 
       if(line.Contains("Session start")) 
       { 
        countStarts++; 
        sessions.Add(line.Substring(line.IndexOf("["), line.LastIndexOf("]") - line.IndexOf("["))); 
       } 
       if (line.Contains("Session end")) 
       { 
        countEnds++; 
        sessions.Remove(line.Substring(line.IndexOf("["), line.LastIndexOf("]") - line.IndexOf("["))); 
       } 
      } 
     } 

     txtStarts.Text = countStarts.ToString(); 
     txtEnds.Text = countEnds.ToString(); 
     txtDifference.Text = (countStarts - countEnds).ToString(); 

     listBox1.DataSource = sessions; 
    } 

Odpowiedz

38

można przekazać do FileStream StreamReader i utworzyć FILESTREAM z właściwą wartość fileshare. Na przykład:

using (var file = new FileStream (openFileDialog1.FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
using (var reader = new StreamReader (file, Encoding.Unicode)) { 
} 
+0

+1 to działa ładnie. Dziękuję Ci. Chociaż musiałem zamienić "var" na FileStream i StreamReader. Do czego zmierzyć var? Czy to VB? Myślę, że ta odpowiedź powinna być edytowana, aby zmienić te, ale nie mam przedstawiciela, aby to zrobić samodzielnie. –

+6

O słowach kluczowych "var", zobacz ten link: http://msdn.microsoft.com/en-us/library/bb383973 .aspx. To słowo kluczowe jest nowe w C# 3.0+. – pyrocumulus

+0

Aha. Chmurka dzięki. Odpowiada mi za pracę w ciemnych wiekach. Wstyd Nie mogę dać +1 komentarzowi :-) –

6

myślałem, że dodać pewien kontekst, StreamReader nie zablokować plik do czytania tylko do pisania wista to jest odczytywany. Spójrz na poniższy kod z klasy StreamReader.

new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, FileOptions.SequentialScan); 

Wskazówka domyślny parametr FileAccess.Read podjęte na MSDN http://msdn.microsoft.com/en-us/library/system.io.fileshare.aspx

Umożliwia późniejsze otwarcie pliku do odczytu. Jeśli ta flaga nie zostanie określona, ​​każde żądanie otwarcia pliku do odczytu (przez ten proces lub inny proces) zakończy się niepowodzeniem, dopóki plik nie zostanie zamknięty. Jednak nawet jeśli ta flaga zostanie określona, ​​dodatkowe uprawnienia mogą nadal być potrzebne, aby uzyskać dostęp do pliku.

Ponownie wzięty z MSDN, aby umożliwić czytanie i zapisywanie, użyj zamiast tego FileAccess.ReadWrite (zgodnie z sugestią Jb Evaina).

Umożliwia późniejsze otwieranie pliku do odczytu lub zapisu. Jeśli ta flaga nie zostanie określona, ​​każde żądanie otwarcia pliku do odczytu lub zapisu (przez ten proces lub inny proces) zakończy się niepowodzeniem, aż plik zostanie zamknięty. Jednak nawet jeśli ta flaga zostanie określona, ​​dodatkowe uprawnienia z serii będą nadal potrzebne do uzyskania dostępu do pliku.

Powiązane problemy