MemoryStream - 无法访问已关闭的Stream

时间:2012-06-07 15:10:21

标签: c# asp.net .net

为什么using (var sw = new StreamWriter(ms))会返回Cannot access a closed Stream exceptionMemory Stream位于此代码之上。

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
}

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

6 个答案:

答案 0 :(得分:78)

这是因为StreamReader在处理时会自动关闭基础流。 using语句会自动执行此操作。

但是,您正在使用的StreamWriter仍在尝试处理流(同样,作者的using语句现在正在尝试处理StreamWriter,然后试图关闭流。)

解决此问题的最佳方法是:不要使用using并且不要处置StreamReaderStreamWriter。请参阅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());                        
}

如果您对swsr进行垃圾收集感到不满意而未在代码中处理(按照推荐),您可以这样做:

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

答案 1 :(得分:9)

从.net45开始,您可以使用LeaveOpen的{​​{1}}构造函数参数,并使用StreamWriter语句。

using

答案 2 :(得分:5)

当StreamReader的using()结束时,它会处理对象并关闭StreamWriter仍在尝试使用的流。

答案 3 :(得分:1)

当它从using语句中退出时,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 :(得分:1)

问题是这个块:

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

StreamReader关闭时(离开使用后),它也会关闭它的基础流,所以现在MemoryStream已关闭。当StreamWriter关闭时,它会尝试将所有内容刷新到MemoryStream,但它已关闭。

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

答案 5 :(得分:0)

在我的情况下(诚然非常神秘且不太可能经常复制),这导致了问题(此代码与使用iTextSharp的PDF生成有关):

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

显示3个细胞/圆柱形表的声明,然后仅为宽度设置两个val是导致问题的原因。一旦我将“PdfPTable(3)”更改为“PdfPTable(2)”,问题就出现了对流烤箱。