lettura e scrittura simultanea di un file in C #

Ho un file contenente i dati su cui mi piacerebbe monitorare le modifiche e aggiungere modifiche personali. Pensa come “Tail -f foo.txt”.

Sulla base di questo thread , sembra che dovrei creare un filestream e passarlo sia a uno scrittore che a un lettore. Tuttavia, quando il lettore raggiunge la fine del file originale, non riesce a vedere gli aggiornamenti che scrivo da solo.

So che sembra una situazione strana … è più un esperimento per vedere se può essere fatto.

Ecco il caso di esempio che ho provato:


foo.txt:
un
B
c
d
e
f


    string test = "foo.txt"; System.IO.FileStream fs = new System.IO.FileStream(test, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite); var sw = new System.IO.StreamWriter(fs); var sr = new System.IO.StreamReader(fs); var res = sr.ReadLine(); res = sr.ReadLine(); sw.WriteLine("g"); sw.Flush(); res = sr.ReadLine(); res = sr.ReadLine(); sw.WriteLine("h"); sw.Flush(); sw.WriteLine("i"); sw.Flush(); sw.WriteLine("j"); sw.Flush(); sw.WriteLine("k"); sw.Flush(); res = sr.ReadLine(); res = sr.ReadLine(); res = sr.ReadLine(); res = sr.ReadLine(); res = sr.ReadLine(); res = sr.ReadLine(); 

    Dopo aver superato “f”, il lettore restituisce null.

    Ok, due modifiche dopo …

    Questo dovrebbe funzionare. La prima volta che l’ho provato, penso di aver dimenticato di impostare FileMode.Append su oStream.

     string test = "foo.txt"; var oStream = new FileStream(test, FileMode.Append, FileAccess.Write, FileShare.Read); var iStream = new FileStream(test, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); var sw = new System.IO.StreamWriter(oStream); var sr = new System.IO.StreamReader(iStream); var res = sr.ReadLine(); res = sr.ReadLine(); sw.WriteLine("g"); sw.Flush(); res = sr.ReadLine(); res = sr.ReadLine(); sw.WriteLine("h"); sw.Flush(); sw.WriteLine("i"); sw.Flush(); sw.WriteLine("j"); sw.Flush(); sw.WriteLine("k"); sw.Flush(); res = sr.ReadLine(); res = sr.ReadLine(); res = sr.ReadLine(); res = sr.ReadLine(); res = sr.ReadLine(); res = sr.ReadLine(); 

    @mikerobi è corretto, quando scrivi nello stream il puntatore del file viene cambiato e spostato alla fine dello stream. Quello su cui non state contando è che StreamReader ha il suo buffer. Legge 1024 byte dal file e otterrai i risultati da quel buffer. Fino a quando il buffer non si esaurisce, quindi deve leggere di nuovo da FileStream. Non trovando nulla perché il puntatore del file si trova alla fine del file.

    Hai davvero bisogno di separare FileStreams, ognuno con il proprio puntatore di file per avere qualche speranza di farlo funzionare.

    Credo che ogni volta che scrivi un personaggio, stai facendo avanzare la posizione del stream, quindi la prossima lettura tenta di leggere dopo il personaggio che hai appena scritto. Ciò accade perché il tuo lettore di stream e lo stream writer utilizzano lo stesso FileStream. Usa un filestream diverso oppure cerca -1 caratteri nello stream dopo ogni scrittura.

    È altamente improbabile che tu possa essere felice con qualsiasi soluzione a questo problema che implica l’utilizzo dello stesso stream per la lettura e la scrittura. Questo è particolarmente vero se stai cercando di leggere la coda del file usando uno StreamReader .

    Si desidera avere due flussi di file diversi. Il stream di scrittura può essere uno StreamWriter se lo desideri. Il stream di lettura dovrebbe essere un stream binario (ad es. Creare con File.OpenRead o FileStream.Create ), leggere i byte non elaborati dal file e convertirlo in testo. La mia risposta a questa domanda mostra le basi di come è fatto.

    Se aggiungi una chiamata a StreamReader.DiscardBufferedData() , cambia il comportamento?