2012-06-07 131 views
38

Hola por qué using (var sw = new StreamWriter(ms)) devuelve Cannot access a closed Streamexception. Memory Stream se encuentra en la parte superior de este código.MemoryStream - No se puede acceder a un Stream cerrado

using (var ms = new MemoryStream()) 
{ 
    using (var sw = new StreamWriter(ms)) 
    {     
     sw.WriteLine("data"); 
     sw.WriteLine("data 2"); 
     ms.Position = 0; 
     using (var sr = new StreamReader(ms)) 
     { 
      Console.WriteLine(sr.ReadToEnd());       
     } 
    } //error here 
} 

¿Cuál es la mejor manera de arreglarlo? Gracias

+0

Esto puede deberse a que está creando StreamWriter y StreamReader desde el mismo MemoryStream. Puede intentar usar dos MemoryStreams diferentes: una para el lector y otra para el escritor. – NKamrath

+0

Posible duplicado de http://stackoverflow.com/questions/2331675/cannot-access-closed-stream – bytebuster

Respuesta

62

Esto se debe a la StreamReader cierra la secuencia subyacente automáticamente cuando siendo eliminado. La instrucción using hace esto automáticamente.

Sin embargo, el StreamWriter está utilizando todavía está tratando de trabajar en la corriente (también, la declaración using para el escritor está tratando de deshacerse de la StreamWriter, que a su vez está tratando de cerrar la secuencia).

La mejor manera de solucionar esto es: no use using y no deseche StreamReader y StreamWriter. Ver this question.

using (var ms = new MemoryStream()) 
{ 
    var sw = new StreamWriter(ms); 
    var sr = new StreamReader(ms); 

    sw.WriteLine("data"); 
    sw.WriteLine("data 2"); 
    ms.Position = 0; 

    Console.WriteLine(sr.ReadToEnd());       
} 

Si se siente mal por sw y sr siendo recolección de basura sin ser eliminados de su código (como se recomienda), que podría hacer algo así:

StreamWriter sw = null; 
StreamReader sr = null; 

try 
{ 
    using (var ms = new MemoryStream()) 
    { 
     sw = new StreamWriter(ms); 
     sr = new StreamReader(ms); 

     sw.WriteLine("data"); 
     sw.WriteLine("data 2"); 
     ms.Position = 0; 

     Console.WriteLine(sr.ReadToEnd());       
    } 
} 
finally 
{ 
    if (sw != null) sw.Dispose(); 
    if (sr != null) sr.Dispose(); 
} 
+0

No cabe duda de que estoy asumiendo por qué OP preguntó "¿Cuál es la mejor manera de solucionarlo?" –

+0

¿Qué tal cerrar var sw = new StreamWriter (ms); var sr = new StreamReader (ms);? –

+0

No tiene que preocuparse por ellos. Cito la respuesta aceptada de la pregunta que he vinculado: * Debería esté bien dejando el StreamReader fuera del alcance si necesita usar el flujo subyacente directamente. Solo asegúrese de disponer el flujo subyacente manualmente cuando sea apropiado. * En otras palabras: mientras el lector y el escritor no se eliminan explícitamente, será basura recolectada al final. Pero editaré otra vez para dar otra solución posible. –

1

cuando se sale de la instrucción using el método Dispose se llamará automáticamente cerrar el flujo

tratar el siguiente:

using (var ms = new MemoryStream()) 
{ 
    var sw = new StreamWriter(ms); 

     sw.WriteLine("data"); 
     sw.WriteLine("data 2"); 
     ms.Position = 0; 
     using (var sr = new StreamReader(ms)) 
     { 
      Console.WriteLine(sr.ReadToEnd()); 
     } 
}  
4

Cuando el uso de() porque su StreamReader está finalizando, está eliminando el objeto y cerrando la transmisión, que su StreamWriter todavía está tratando de usar.

+0

No cabe duda de que estoy asumiendo por qué OP preguntó "¿Cuál es la mejor manera? para arreglarlo? " –

+1

No hay duda de por qué sigues diciendo esto :-) – camainc

1

El problema es que este bloque:

using (var sr = new StreamReader(ms)) 
{ 
    Console.WriteLine(sr.ReadToEnd());       
} 

Cuando el StreamReader está cerrado (después de dejar el uso), se cierra se subyacente corriente, así, por lo que ahora el MemoryStream está cerrada. Cuando el StreamWriter se cierra, intenta vaciar todo al MemoryStream, pero está cerrado.

Considere no poner el StreamReader en un bloque usando.

2

En mi caso (la verdad es muy arcano y no es probable que se reproduce a menudo), esta fue la causa del problema (el código está relacionado con la generación de PDF usando iTextSharp):

PdfPTable tblDuckbilledPlatypi = new PdfPTable(3); 
float[] DuckbilledPlatypiRowWidths = new float[] { 42f, 76f }; 
tblDuckbilledPlatypi.SetWidths(DuckbilledPlatypiRowWidths); 

La declaración de un grupo 3- la tabla celled/columned, y luego establecer solo dos vals para el ancho fue lo que causó el problema, al parecer. Una vez que cambié "PdfPTable (3)" a "PdfPTable (2)", el problema fue el camino del horno de convección.

+0

Esta debería ser otra pregunta + respuesta. No tiene nada que d o con problema de OP Si bien puede ser muy útil para los usuarios de 'iTextSharp', la forma en que usted brinda ayuda a los demás es incorrecta (¿lo pone en una pregunta aleatoria con solo un texto de excepción similar?) – Sinatr

Cuestiones relacionadas