asp.net MemoryStream -无法访问已关闭的流

xpcnnkqh  于 12个月前  发布在  .NET
关注(0)|答案(7)|浏览(190)

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

字符串

5uzkadbs

5uzkadbs1#

这是因为StreamReader在被释放时会自动关闭底层流。using语句会自动执行此操作。
但是,您正在使用的StreamWriter仍在尝试处理流(此外,writer的using语句现在正在尝试释放StreamWriter,然后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();
}

tktrz96b

tktrz96b2#

自.net45起,您可以使用StreamWriterLeaveOpen构造函数参数,并且仍然使用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());
    }
}

字符串

oaxa6hgo

oaxa6hgo3#

StreamReaderusing()结束时,它会释放对象并关闭流,而StreamWriter仍在尝试使用该流。

wgxvkvu9

wgxvkvu94#

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

字符串

ru9i0ody

ru9i0ody5#

问题就出在这个区块:

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

字符串
StreamReader关闭时(在离开using之后),它也关闭了它的底层流,所以现在MemoryStream关闭了。当StreamWriter关闭时,它试图将所有内容刷新到MemoryStream,但它关闭了。
您应该考虑不要将StreamReader放在using块中。

i34xakig

i34xakig6#

你必须让流打开才能读取它。“StreamWriter”在完成写入后关闭它

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

字符串

iih3973s

iih3973s7#

在我的例子中(诚然非常《双城之战》,不太可能经常被复制),这是导致问题的原因(这段代码与使用iTextSharp生成PDF有关):

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

字符串
声明一个3-cell/columned表,然后只设置两个值的宽度是导致问题的原因。一旦我将“PdfPTable(3)”改为“PdfPTable(2)”,问题就像对流烤箱一样。

相关问题