2010-03-10 19 views
42

Qual è la differenza di funzionalità tra StreamWriter.Flush() e StreamWriter.Close()?Qual è la differenza tra StreamWriter.Flush() e StreamWriter.Close()?

Quando i miei dati non venivano scritti correttamente in un file, ho aggiunto sia Flush() e Close() alla fine del mio codice. Tuttavia, mi sono reso conto che aggiungere oFlush() o Close() consentiva la corretta scrittura dei dati.

Non sono stato in grado di capire esattamente cosa fanno ciascuno di questi metodi quando leggo i documenti MSDN; Ho solo capito che l'uno o l'altro è necessario per garantire che i dati siano scritti correttamente. Ogni ulteriore spiegazione sarebbe molto apprezzata.


Dove s è una stringa da scrivere, ecco quello che il mio codice è simile al momento:

 StreamWriter sw = File.CreateText("TextOutput.txt"); 
     sw.Write(s); 
     sw.Flush(); 
     sw.Close(); 

Sulla base del feedback dalle risposte, ho riscritto il mio codice in un using block, che implementa IDisposable e si occuperà automaticamente di scrivere il flusso sul file quando l'oggetto viene eliminato:

 using (StreamWriter sw = File.CreateText("TextOutput.txt")) 
     { 
      sw.Write(s); 
     } 

risposta

85

StreamWriter.Flush() può essere chiamato ogni volta che è necessario cancellare il buffer e il flusso rimarrà aperto.

StreamWriter.Close() è per la chiusura del flusso, a questo punto viene anche scaricato il buffer.

Ma non dovresti davvero chiamare nessuno di questi. Ogni volta che vedo un codice .Close() lo prendo come un odore di codice, perché in genere significa che un'eccezione imprevista potrebbe far sì che la risorsa venga lasciata aperta. Che cosa si dovrebbe fare, è creare la variabile StreamWriter in un blocco utilizzando, in questo modo:

using (var writer = new StreamWriter("somefilepath.txt")) 
{ 
    // write a bunch of stuff here 
} // the streamwriter WILL be closed and flushed here, even if an exception is thrown. 
+12

Questo perché Stream.Dispose chiama Close() – munissor

+0

per essere chiaro, che incapsula un oggetto 'StreamWriter' in un blocco' using' (o 'try' /' catch') costringerà l'oggetto a essere chiuso? –

+4

@ Ben - incapsulandolo in un try/catch non lo forzerà a chiudere. Incapsulare la tua chiamata '.Close()' in un blocco 'finally' o' using', e un blocco using è molto più conveniente. –

0

Da MSDN:

Flush: cancella tutti i buffer per lo scrittore corrente e provoca tutti i dati nel buffer di essere scritto nel flusso sottostante.

Chiudi: chiude l'oggetto StreamWriter corrente e il flusso sottostante.

11

StreamWriter.Flush() svuota qualsiasi cosa nel flusso verso il file. Questo può essere fatto nel mezzo dell'uso dello Stream e puoi continuare a scrivere.

StreamWriter.Close() chiude il flusso per la scrittura. Ciò include Flushing the Stream un'ultima volta.

C'è un modo migliore di fare le cose però. Poiché StreamWriter implementa IDisposable, è possibile racchiudere StreamWriter in un blocco using.

using(StreamWriter sw = new StreamWriter(stream)) 
{ 
    // Work with things here 
} 

Dopo il blocco using, saranno chiamati Dispose ... che filo e chiudere il flusso per voi.

1

Flush forze per scrivere buffer su disco. Chiudi: chiude lo stream e viene eseguita anche l'operazione di svuotamento interno

+1

Per i flussi di file, Close e Flush scrivono nella cache del disco di ritardo scrittura del sistema operativo, ma non attraverso il disco. Devi usare FileStream's Flush (true). È stato aggiunto in .NET 4.0 ma è rotto. Il link del bug dice risolto, ma non fornisce alcuna indicazione su quale versione è stata corretta: http://connect.microsoft.com/VisualStudio/feedback/details/634385/filestream-flush-flushtodisk-true-call-does-not-flush -the-buffers-to-disk # details – jimvfr

4

Avevo un caso in cui stavo scrivendo una stringa molto lunga su un StreamWriter con un MemoryStream sottostante. Il MemoryStream veniva consumato da qualcos'altro prima che lo scrittore e il flusso fossero disposti.

using (var memoryStream = new MemoryStream()) 
using (var streamWriter = new StreamWriter(memoryStream , Encoding.UTF8)) 
{ 
    streamWriter.Write(someRealyLongStringValue); 
    DoSomethingWithTheStream(memoryStream); 
} 

Con stringhe molto lunghe, la fine della stringa veniva troncata. Questo è stato risolto chiamando il flush prima che il flusso venisse usato. In alternativa avrei potuto impostare AutoFlush su true.

+0

Grazie, mi sono imbattuto in questo problema me stesso. – Coxy

Problemi correlati