¿Desechar streamreader cierra la transmisión?


Estoy enviando una secuencia a los métodos para escribir, y en esos métodos estoy usando un lector binario/wrtier. Cuando el lector / escritor se dispone, ya sea por using o simplemente cuando no se hace referencia a él, es la corriente cerrada también??

Enviaría un lector/Escritor BinaryReader, pero estoy usando un StreamReader también (tal vez debería ir alrededor de eso. Solo estoy usando eso para GetLine y ReadLine). Esto es bastante problemático si cierra la transmisión cada vez que un escritor/lector se cierra.

Author: Chris Cudmore, 2009-06-30

7 answers

Sí, StreamReader, StreamWriter, BinaryReader y BinaryWriter todos cierran/eliminan sus flujos subyacentes cuando llamas Dispose a ellos. Ellos no desechan el flujo si el lector/escritor es solo basura recolectada, sin embargo, siempre debe desechar el lector/escritor, preferiblemente con una declaración using. (De hecho, ninguna de estas clases tiene finalizadores, ni debería tenerlos.)

Personalmente prefiero tener una sentencia using para la secuencia también. Puede anidar using declaraciones sin tirantes bastante prolijamente:

using (Stream stream = ...)
using (StreamReader reader = new StreamReader(stream, Encoding.Whatever))
{
}

A pesar de que la instrucción using para el flujo es algo redundante (a menos que el constructor StreamReader lance una excepción) lo considero una buena práctica, ya que si se deshace del StreamReader y solo use el flujo directamente en una fecha posterior, ya tendrá la semántica de eliminación correcta.

 175
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-30 18:23:10

Esta es una vieja, pero hoy quería hacer algo similar y descubrí que las cosas han cambiado. Desde. net 4.5, hay un argumento leaveOpen:

public StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen )

El único problema es que no es del todo obvio qué establecer para los otros parámetros. Aquí hay algo de ayuda:

De la página msdn para el constructor StreamReader (Stream):

Este constructor inicializa la codificación a UTF8Encoding, el Propiedad BaseStream usando la secuencia parámetro, y el interno tamaño del búfer a 1024 bytes.

Que sólo deja detectEncodingFromByteOrderMarks que a juzgar por el código fuente es true

public StreamReader(Stream stream)
        : this(stream, true) {
}

public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
        : this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}

Sería bueno si algunos de esos valores predeterminados estuvieran expuestos o si los argumentos fueran opcionales para que pudiéramos especificar los que queremos.

 33
Author: acarlon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-12 04:55:13

Sí, lo hace. Puede verificar esto mirando la implementación con Reflector.

protected override void Dispose(bool disposing)
{
    try
    {
        if ((this.Closable && disposing) && (this.stream != null))
        {
            this.stream.Close();
        }
    }
    finally
    {
        if (this.Closable && (this.stream != null))
        {    
            this.stream = null;    
            this.encoding = null;
            this.decoder = null;
            this.byteBuffer = null;
            this.charBuffer = null;
            this.charPos = 0;
            this.charLen = 0;
            base.Dispose(disposing);
        }
    }
}
 27
Author: Brian Rasmussen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-30 18:22:51

Seis años de retraso, pero tal vez esto podría ayudar a alguien.

StreamReader cierra la conexión cuando está dispuesta. Sin embargo, " usando (Stream stream = ...){...} "con StreamReader / StreamWriter puede resultar en que la Secuencia sea eliminada dos veces: (1) cuando el objeto StreamReader es eliminado (2) y cuando la Secuencia usando bloque se cierra. Esto da como resultado una advertencia CA2202 cuando se ejecuta el análisis de código de VS.

Otra solución, tomada directamente de la página CA2202 , es usar un intentar / finalmente bloquear. Configure correctamente, esto solo cerrará la conexión una vez.

Cerca de la parte inferior de CA2202 , Microsoft recomienda usar lo siguiente:

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    if(stream != null)
        stream.Dispose();
}

En lugar de...

// Generates a CA2202 warning
using (Stream stream = new FileStream("file.txt", FileMode.Open))
using (XmlReader reader = new XmlReader (stream))
{
    // Use the reader object...
}
 10
Author: Sunsetquest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-13 21:11:21

Sí. Llamar a Dispose () on e IDesposable (lo que hace "using") debería hacer que un objeto limpie todos sus recursos. Esto incluye flujos de descarga y cierre de sus descriptores de archivo.

Si, en su caso, desea pasarlo a otros métodos, entonces debe asegurarse de que esos métodos no hagan su lectura/escritura en un bloque de uso.

 2
Author: Joe M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-30 18:22:55

Una manera fácil de solucionar esto si lo necesita es anular el método StreamWriter classes Dispose. Ver mi post aquí para el código sobre cómo hacerlo:

Lo hace .Deshacerse de un StreamWriter cerrar la corriente subyacente?

 1
Author: Aaron Murgatroyd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:32

La secuencia eliminada ya sea mediante la palabra clave" using " o llamando a dispose explícitamente

 -3
Author: Ahmed Said,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-30 18:22:04