2012-06-07 105 views
38

嗨原因using (var sw = new StreamWriter(ms))返回Cannot access a closed StreamexceptionMemory Stream是在此代码的顶部。MemoryStream - 无法访问已关闭的流

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 
} 

修复它的最佳方法是什么? 感谢

+0

这可能是因为您是从同一个MemoryStream创建StreamWriter和StreamReader。您可以尝试使用两种不同的MemoryStreams:一种用于读者,一种用于写作者。 – NKamrath

+0

可能的重复http://stackoverflow.com/questions/2331675/cannot-access-closed-stream – bytebuster

回答

62

这是因为StreamReader时自动关闭底层流被处置。 using声明自动执行此操作。

然而,StreamWriter你使用仍试图对工作流(也行,using语句作家目前正试图处置StreamWriter,然后试图关闭流的)。

解决此问题的最佳方法是:请勿使用using并且不要处置StreamReaderStreamWriter。见this question。当使用

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

有没有什么疑问,我假设为什么OP问:“什么是最好的方法来解决它?“ –

+0

关于var sw = new StreamWriter(ms); var sr = new StreamReader(ms);? –

+0

你不需要担心它们,我引用来自问题的接受答案:*你应该如果您需要直接使用基础流,请保持StreamReader超出范围,只要确保在适当的时候手动处理基础流*换句话说:虽然读者和作者没有明确处理,但是他们我将再次编辑以提供另一种可能的解决方案 –

1

,当它从使用语句Dispose方法将被自动调用关闭流

失控尝试以下:

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

():

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());       
} 

如果你觉得不好swsr被当作垃圾回收,而不在您的代码被设置的(推荐),你可以做这样的事情因为您的StreamReader正在结束,它正在处理对象并关闭StreamWriter仍在尝试使用的流。

+0

有没有什么疑问,我假设为什么OP问“什么是最好的方法解决它?“ –

+1

毫无疑问,你为什么一直说这个:-) – camainc

1

问题是这样的块:

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

StreamReader被关闭(在使用后离开),它关闭它的底层流以及,所以现在MemoryStream被关闭。当StreamWriter被关闭时,它会尝试清除所有内容到MemoryStream,但它被关闭。

您应该考虑不要将StreamReader放在使用区块中。

2

在我的情况(当然很神秘,不容易被经常转载),这是造成问题(此代码与使用iTextSharp的PDF生成):

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

3元的声明celled/columned表格,然后设置宽度的两个val是显然导致问题的原因。一旦我将“PdfPTable(3)”更改为“PdfPTable(2)”,问题就变成了对流烤箱的方式。

+0

这应该是另一个问题+答案。 o与OP问题。虽然对于iTextSharp用户来说,提供帮助的方式是错误的(把它置于随机问题中,只有类似的异常文本)。 – Sinatr

相关问题