90

嗨,为什么 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
}

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

4

6 回答 6

129

This is because the StreamReader closes the underlying stream automatically when being disposed of. The using statement does this automatically.

However, the StreamWriter you're using is still trying to work on the stream (also, the using statement for the writer is now trying to dispose of the StreamWriter, which is then trying to close the stream).

The best way to fix this is: don't use using and don't dispose of the StreamReader and StreamWriter. See 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());                        
}

If you feel bad about sw and sr being garbage-collected without being disposed of in your code (as recommended), you could do something like that:

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();
}
于 2012-06-07T15:16:33.247 回答
33

从 .net45 开始,您可以使用LeaveOpen构造函数参数StreamWriter并且仍然使用该using语句。例子:

using (var ms = new MemoryStream())
{
    using (var sw = new StreamWriter(ms, leaveOpen:true))
    {
        sw.WriteLine("data");
        sw.WriteLine("data 2");    
    }

    ms.Position = 0;
    using (var sr = new StreamReader(ms))
    {
        Console.WriteLine(sr.ReadToEnd());
    }
}
于 2018-04-13T11:49:55.207 回答
8

When the using() for your StreamReader is ending, it's disposing the object and closing the stream, which your StreamWriter is still trying to use.

于 2012-06-07T15:16:48.633 回答
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());
        }
}    
于 2012-06-07T15:13:13.637 回答
1

问题是这个块:

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

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

您应该考虑不要将其StreamReader放入 using 块中。

于 2012-06-07T15:17:32.463 回答
0

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

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

显然,声明一个 3 单元格/列的表,然后只为宽度设置两个 val 是导致问题的原因。一旦我将“PdfPTable(3)”更改为“PdfPTable(2)”,问题就出现在对流烤箱上。

于 2015-05-18T20:45:15.313 回答