2012-10-24 12 views
7

Possiedo un StreamWriter il cui stream sottostante è un FileStream. Il seguente codice garantisce che lo FileStream svuota anche il proprio buffer nel file effettivo sul file system o è necessario chiamare esplicitamente lo Flush() su FileStream?Will StreamWriter.Flush() chiama anche FileStream.Flush()?

using (var fs = new FileStream("blabla", FileMode.Append)) { 
    using (var sw = new StreamWriter(fs)) { 
     sw.WriteLine("Hello, I want to be flushed."); 
     sw.Flush(); //I need this to also flush onto the file, not just to the FileStream 
    } 
} 

Come da MSDN, "Lavaggio del flusso non svuotare il suo codificatore sottostante a meno che non si chiama esplicitamente Flush o Chiudi", ma non si sa se un FileStream può essere considerato un "encoder sottostante".

Inoltre, se non si specifica FileOptions.WriteThrough, sono sicuro che il sistema operativo scriverà la linea scaricata sul disco anche se il programma si arresta prima che i due flussi siano stati chiusi (supponendo, ad esempio, nessun blocco , solo una chiamata a Flush())?

Nel mio scenario ho bisogno di lasciare il flusso aperto (per la registrazione), quindi non posso usare i blocchi using {}, ma vorrei assicurarmi che i dati vengano sempre scritti sul disco anche se il programma si blocca. Posso permettermi di perdere i dati se c'è un arresto di alimentazione e il sistema operativo non è stato scaricato sul disco, ma altrimenti ho bisogno che il sistema operativo si svuota anche se non ho mai chiamato correttamente lo streaming Close().

+0

Perché non l'hai provato tu stesso? – opewix

+0

Sono interessato a sapere se il comportamento è garantito e possiamo fare affidamento su di esso, non sul fatto che funzioni la maggior parte del tempo. –

+0

sì, lo svuotamento del flusso sottostante. Cancella tutti i buffer per il writer corrente e fa in modo che tutti i dati bufferizzati vengano scritti nel flusso sottostante. – opewix

risposta

7

Sì, chiamando Flush su StreamWriter farà sì che il flusso sottostante per essere Flush ed. Il 4.5 Versione chiama una Flush(bool,bool) funzione privata, che si conclude con:

if (flushStream) 
{ 
    this.stream.Flush(); 
} 

Dove flushStream è il primo parametro, this.stream è il torrente che la StreamWriter è stato costruito su, e la chiamata in Flush() è Flush(true,true).


(parti più vecchie di risposta - io ero molto rotonda nel rispondere Mosso parte più rilevante della risposta alla cima.)

Non è esplicitamente precisato nella documentazione ovunque posso trovarlo, ma qualsiasi la classe di flusso che viene costruita passandole un altro flusso dovrebbe essere considerata come "assumere la proprietà" di quel flusso (a meno che non sia specificatamente chiamato altrimenti).

Cioè, una volta costruito lo StreamWriter utilizzando fs, non si dovrebbero eseguire azioni dirette su fs.


La parte che hai citato da MSDN riguarda le frasi successive:

Questo permette al codificatore di mantenere il suo stato (caratteri parziali) in modo che possa codificare correttamente il successivo blocco di caratteri. Questo scenario influisce su UTF8 e UTF7 in cui determinati caratteri possono essere codificati solo dopo che il codificatore riceve il carattere o i caratteri adiacenti.

Cioè, potresti aver passato i dati a Write in modo tale che gli hai fornito alcuni surrogati Unicode, ma non un carattere completo. Flush non scriverà quei sostituti allo stream. Fino a quando passerai sempre stringhe ben formate (complete) a Write, non dovrai preoccuparti di questo.


+0

Grazie, questo aiuta molto. E la seconda parte della domanda? Informazioni sulla garanzia che il sistema operativo scriverà effettivamente il Flush ad un certo punto nel tempo anche se Stream non viene mai chiuso correttamente e FileOptions.WriteThrough NON è specificato nel costruttore FileStream? –

+0

@ErwinMayer - Non sono sicuro di aver capito la domanda. Se ** ** assolutamente **, ** sicuramente **, * deve * garantire che questi dati colpiscano il disco, allora quasi sicuramente dovrai specificare 'WriteThrough' - ma avrai anche bisogno di una macchina con un enclosure del disco con batteria di backup, ecc. In caso contrario, penso che ci sarà sempre una piccola finestra di rischio. Non so per quanto tempo questa finestra di rischio è, ed è probabile che il sistema operativo (e probabilmente la configurazione del sistema operativo, il driver, ecc.) Dipenda, quindi non è ben definito all'interno di .NET framework. –

+0

Vero, nel mio caso finché le istruzioni per scrivere i dati sul disco sono inviate al sistema operativo, sto bene. Non mi importa se il sistema operativo non scrive immediatamente sul disco. Voglio solo assicurarmi che il sistema operativo scriva i dati scaricati anche se il programma si è interrotto e gli stream non sono stati chiusi correttamente. –

4

Lo smaltimento di flussi è garantito se utilizzato con utilizzando il blocco!

Con una catena di flussi, chiudendo il flusso esterno (a capo della catena) i.e StreamWriter in your case chiude l'intero lotto i.e FileStream

forze metodo Flush cuscinetto interno da scrivere immediately.Flush viene chiamato automaticamente quando stream è closed, quindi non è necessario effettuare le seguenti operazioni

s.Flush();s.Close();

quindi, il momento in cui i s maggior parte dei più alti tream è chiuso, scarica e poi chiude i flussi sottostanti che scaricano anche i contenuti.

Per esempio considerano questa catena

FileStream->GZipStream->StreamWriter 

Quindi, il momento in cui si chiude lo StreamWriter

StreamWriter vampate e closes.It chiude anche undelying GZipStream

GzipStream vampate e closes.It chiude anche sottostante FileStream

FileStream flushes e closes

+1

Grazie, so che chiudendo StreamWriter si chiude FileStream, ma la prima parte della domanda si riferisce al fatto che Flush() sia anch'esso in cascata. La seconda parte della domanda riguarda se, nel caso in cui il FileStream NON sia stato eliminato prima di arrestarsi (ad esempio, non si usi l'uso dei blocchi), ma Flush() sia stato chiamato, se il SO ancora scriverà il suo buffer interno disco fisico (a condizione che non vi sia alcun arresto del sistema operativo o spegnimento forzato). –

+0

@ErwinMayer come ho detto, 'flush' viene chiamato automaticamente quando lo stream è chiuso o il buffer è riempito. Nel momento in cui viene chiuso il flusso più alto, svuota e chiude i flussi sottostanti che eseguono il flushing dei flussi. – Anirudha

+0

Sì , comunque sono interessato al caso in cui non chiudiamo alcun flusso ... –

Problemi correlati