2010-03-10 21 views
42

¿Cuál es la diferencia en la funcionalidad entre StreamWriter.Flush() y StreamWriter.Close()?¿Cuál es la diferencia entre StreamWriter.Flush() y StreamWriter.Close()?

Cuando mis datos no se escribieron correctamente en un archivo, agregué Flush() y Close() al final de mi código. Sin embargo, me di cuenta de que agregar Flush() o Close() permitía que los datos se escribieran correctamente.

No pude ver exactamente qué hace cada uno de estos métodos cuando leo los documentos de MSDN; Solo descubrí que uno u otro es necesario para garantizar que los datos estén escritos correctamente. Cualquier otra explicación sería muy apreciada.


Dónde s es una cadena que ser escrito, esto es lo que se ve mi código como actualmente:

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

Con base en la retroalimentación de las respuestas, me he reescrito el código en un using bloque, que implementa IDisposable y se ocupará automáticamente de escribir la secuencia en el archivo cuando se elimine el objeto:

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

Respuesta

85

StreamWriter.Flush() puede llamarse cada vez que necesite borrar el búfer, y la transmisión permanecerá abierta.

StreamWriter.Close() es para cerrar la secuencia, en cuyo punto también se vacía el búfer.

Pero realmente no debería necesitar llamar a ninguno de estos. Cada vez que veo un .Close() en el código, lo tomo como un olor a código, porque generalmente significa que una excepción inesperada podría dejar el recurso abierto. Lo que debe hacer, es crear la variable de StreamWriter en un bloque usando, como esto:

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

Esto porque Stream.Dispose llama a Close() – munissor

+0

para ser claro, enapsulating un objeto 'StreamWriter' en un bloque' using' (o 'try' /' catch') obligará al objeto a cerrarse? –

+4

@Ben - encapsularlo en un try/catch _no lo obligará a cerrar. Encapsular su llamada '.Close()' en un bloque 'finally' o' using' y en un bloque de uso es mucho más conveniente. –

0

De MSDN:

Flush: Borra todos los tampones para el escritor actual y hace que los datos almacenados temporalmente para ser escrito en la secuencia subyacente.

Cerrar: cierra el objeto StreamWriter actual y la secuencia subyacente.

11

StreamWriter.Flush() vaciará cualquier cosa en el flujo al archivo. Esto se puede hacer en el medio de usar Stream y puede seguir escribiendo.

StreamWriter.Close() cierra el flujo para la escritura. Esto incluye Flushing the Stream por última vez.

Sin embargo, hay una manera mejor de hacer las cosas. Como StreamWriter implementa IDisposable, puede ajustar el StreamWriter en un bloque using.

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

Después de que el bloque de using, Dispose se llamará ... lo cual hará que se vacíe y cerrar la secuencia para usted.

1

Flush fuerzas para escribir búfer en el disco. Cerrar: cierra el flujo y la operación de lavado interno también se realiza.

+1

Para las transmisiones de archivos, Close y Flush escriben en el caché de disco de retraso de escritura del SO, pero no en el disco. Tienes que usar Flush de FileStream (verdadero). Fue agregado en .NET 4.0 pero está roto. El enlace del error dice "reparado", pero no da ninguna indicación de la versión en la que fue corregido: http://connect.microsoft.com/VisualStudio/feedback/details/634385/filestream-flush-flushtodisk-true-call-does-not-flush -the-buffers-to-disk # details – jimvfr

4

Tenía un caso en el que estaba escribiendo una cadena muy larga en un StreamWriter con un MemoryStream subyacente. El MemoryStream estaba siendo consumido por otra cosa antes de que el escritor y la transmisión fueran eliminados.

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

Con cuerdas realmente largas, el final de la cuerda se estaba truncando. Esto se resolvió llamando al color antes de usar la transmisión. Alternativamente, podría haber configurado AutoFlush en verdadero.

+0

Gracias, acabo de toparme con este problema yo mismo. – Coxy

Cuestiones relacionadas