在XmlWriter周围使用语句会导致流过早关闭

问题描述

我试图将一小段XML写入内存流,然后从内存流中读取写入的内容并将其保存到变量中。

我有以下逻辑可用于编写和读取简单文本值:

string text = null;

using (var memoryStream = new MemoryStream())
{
    using (var streamWriter = new StreamWriter(memoryStream))
    {
        streamWriter.Write("Foo!");
        streamWriter.Flush();

        memoryStream.Position = 0;

        using (var streamReader = new StreamReader(memoryStream))
        {
            text = streamReader.ReadToEnd();
        }
    }
}

await context.Response.WriteAsync(text,Encoding.UTF8);

但是将StreamWriter替换为XmlWriter,然后尝试在ObjectdisposedException中写入实际的XML结果。

string text = null;

using (var memoryStream = new MemoryStream())
{
    using (var xmlWriter = XmlWriter.Create(memoryStream))
    {
        xmlWriter.WriteStartDocument();
        xmlWriter.WriteStartElement("Foo");
        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();

        memoryStream.Position = 0;

        using (var streamReader = new StreamReader(memoryStream))
        {
            text = streamReader.ReadToEnd();
        }
    }
}
System.ObjectdisposedException: Cannot access a closed Stream.
   at System.IO.MemoryStream.Write(Byte[] buffer,Int32 offset,Int32 count)
   at System.Xml.XmlUtf8RawTextWriter.FlushBuffer()
   at System.Xml.XmlUtf8RawTextWriter.Flush()
   at System.Xml.XmlWellFormedWriter.Close()
   at System.Xml.XmlWriter.dispose(Boolean disposing)
   at System.Xml.XmlWriter.dispose()

但是,如果我删除using周围的XmlWriter块...,它将起作用。

string text = null;

using (var memoryStream = new MemoryStream())
{
    var xmlWriter = XmlWriter.Create(memoryStream));

    xmlWriter.WriteStartDocument();
    xmlWriter.WriteStartElement("Foo");
    xmlWriter.WriteEndElement();
    xmlWriter.WriteEndDocument();
    xmlWriter.Flush();

    memoryStream.Position = 0;

    using (var streamReader = new StreamReader(memoryStream))
    {
        text = streamReader.ReadToEnd();
    }
}

await context.Response.WriteAsync(text,Encoding.UTF8);

我无法理解为什么会发生这种情况,为什么我不能在using周围使用TextWriter块。用StreamWriter完成的相同步骤就可以了,所以XmlWriter有什么区别?我假设直到使用块的结尾都不会关闭流。我的思维方式的缺陷在哪里?

解决方法

看一下堆栈跟踪:XmlWriter被放置在其块的末尾时发生了异常。它被处置,刷新,它尝试写入基础流并爆炸! -某些东西已经处置了基础流。

StreamReader的块恰好在XmlWriter的块之前结束,并且这种处置(默认情况下)也处置基础流。这是唯一可以做到的事情。

在其他情况下它起作用的原因是StreamWriter不得在处置时刷新(或者更有可能-不需要 刷新,因为其缓冲区为空或不存在)。这意味着StreamReader之前没有关系。

在最后一种情况下它有效,因为没有XmlWriter被处置,也根本没有尝试冲洗(但是,显然,它并不需要,因为您已经手动冲洗了) ,并且输出是正确的-我想知道为什么它的dispose方法坚持要刷新吗?但是它在做)

这里的一般解决方案是更有选择地使用using。您可以完全忽略StreamReader,也可以将'leaveOpen'参数传递给它。

我通常的方法是只担心处理流,因为流始终是链接到需要处理的非托管资源的流。处置读者和作家实际上只是简洁地处置流的一种好方法。

,

默认情况下,lib处置基础流。如果在处置StreamReader之后需要它(并且StreamReader在处置过程中使用它来执行XmlWriter),则可以将leaveOpen ctor参数设置为Flush

true

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...