C# MemoryStream - 无法访问关闭的流

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10934585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 15:48:59  来源:igfitidea点击:

MemoryStream - Cannot access a closed Stream

c#asp.net.net

提问by Arbejdsgl?de

Hi why using (var sw = new StreamWriter(ms))returns Cannot access a closed Streamexception. Memory Streamis on top of this code.

嗨,为什么 using (var sw = new StreamWriter(ms))回来Cannot access a closed StreamexceptionMemory 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
}

What the best way to fix it ? Thanks

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

采纳答案by Thorsten Dittmar

This is because the StreamReadercloses the underlying stream automatically when being disposed of. The usingstatement does this automatically.

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

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

但是,StreamWriter您正在使用的 仍在尝试处理流(此外,using编写器的语句现在正在尝试处理 ,StreamWriter然后尝试关闭流)。

The best way to fix this is: don't use usingand don't dispose of the StreamReaderand StreamWriter. See this question.

解决此问题的最佳方法是:不要使用using和处理StreamReaderand StreamWriter。看到这个问题

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 swand srbeing garbage-collected without being disposed of in your code (as recommended), you could do something like that:

如果你觉得不好sw,并sr没有在你的代码被设置的(推荐)被垃圾收集,你可以做这样的事情:

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

回答by Massimiliano Peluso

when it gets out from the using statement the Disposemethod will be called automatically closing the stream

当它从 using 语句中退出时,Dispose将调用该方法自动关闭流

try the below:

试试下面的:

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

回答by itsme86

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.

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

回答by vcsjones

The problem is this block:

问题是这个块:

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

When the StreamReaderis closed (after leaving the using), it closes it's underlying stream as well, so now the MemoryStreamis closed. When the StreamWritergets closed, it tries to flush everything to the MemoryStream, but it is closed.

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

You should consider not putting the StreamReaderin a using block.

您应该考虑不要将 放入StreamReaderusing 块中。

回答by B. Clay Shannon

In my case (admittedly very arcane and not likely to be reproduced often), this was causing the problem (this code is related to PDF generation using iTextSharp):

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

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

The declaration of a 3-celled/columned table, and then setting only two vals for the width was what caused the problem, apparently. Once I changed "PdfPTable(3)" to "PdfPTable(2)" the problem went the way of the convection oven.

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

回答by NtFreX

Since .net45 you can use the LeaveOpenconstructor argument of StreamWriterand still use the usingstatement. Example:

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

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

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