2009-10-22 9 views
17

StreamReader blocca un file di testo mentre lo sta leggendo.
Posso forzare lo StreamReader a funzionare in modalità "sola lettura" o "non bloccante"?È possibile impedire a StreamReader di bloccare un file di testo mentre è in uso?

La mia soluzione sarebbe quella di copiare il file in una posizione temporanea e leggerlo da lì, ma preferirei utilizzare lo StreamReader direttamente se possibile. Qualche suggerimento alternativo?

Sfondo:
Ho scritto una piccola app per ottenere alcune statistiche da un file di registro. Questo file viene costantemente aggiornato (più volte al secondo) da un programma esterno che consente di chiamare AAXXYY.

La revisione dell'output suggerisce che la mia app potrebbe bloccare il file e impedire la scrittura di AAXXYY.

Questo è quello che sto facendo

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; 
    } 

risposta

38

È possibile passare un FileStream al StreamReader, e creare il FileStream con il valore FileShare corretta. Per esempio:

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

+1 questo funziona bene. Grazie. Anche se ho dovuto sostituire "var" con FileStream e StreamReader. Cosa doveva fare Var? È quel VB? Penso che questa risposta dovrebbe essere modificata per cambiare quelli, ma non ho il rappresentante per farlo da solo –

+6

Informazioni sulla parola chiave 'var', vedere questo link: http://msdn.microsoft.com/en-us/library/bb383973 aspx. Quella parola chiave è nuova in C# 3.0+. – pyrocumulus

+0

Aha. Grazie al cloud. Mi fa bene per lavorare nei periodi bui. Peccato non posso fare +1 su un commento :-) –

6

Ho pensato di aggiungere qualche contesto, StreamReader non si bloccare un file per la lettura solo per scrivere whist è in corso la lettura. Dai un'occhiata al codice qui sotto della classe StreamReader.

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

Avviso parametro FileAccess.Read di default preso per MSDN http://msdn.microsoft.com/en-us/library/system.io.fileshare.aspx

Consente successiva apertura del file per la lettura. Se questo flag non viene specificato, qualsiasi richiesta di apertura del file per la lettura (tramite questo processo o un altro processo) avrà esito negativo fino alla chiusura del file. Tuttavia, anche se questo flag è specificato, potrebbero essere necessarie ulteriori autorizzazioni per accedere al file.

Ancora preso da MSDN per consentire la lettura e la scrittura, utilizzare invece FileAccess.ReadWrite (come suggerito da Jb Evain).

Permette la successiva apertura del file per la lettura o la scrittura. Se questo flag non viene specificato, qualsiasi richiesta di apertura del file per la lettura o scrittura (tramite questo processo o un altro processo) avrà esito negativo finché il file non viene chiuso. Tuttavia, anche se questo flag è specificato, potrebbero essere necessarie ulteriori autorizzazioni per accedere al file.

Problemi correlati