XmlDocument.Save OutOfMemory异常

时间:2012-11-24 21:51:32

标签: c# xml xmldocument

我一直在使用这个方便的功能来“美化”xml文档,因此它使用缩进和换行符进行格式化。但是对于更大的文档(~1MB),由于某种原因,我在doc.Save(writer)处得到OutOfMemoryException。我该如何解决这个问题?

public static string BeautifyXmlDocument(XmlDocument doc)
{
    MemoryStream sb = new MemoryStream();
    XmlWriterSettings s = new XmlWriterSettings();
    s.Indent = true;
    s.IndentChars = "  ";
    s.NewLineChars = "\r\n";
    s.NewLineHandling = NewLineHandling.Replace;
    s.Encoding = new UTF8Encoding(false);
    XmlWriter writer = XmlWriter.Create(sb, s);
    doc.Save(writer);
    writer.Close();
    return Encoding.UTF8.GetString(sb.ToArray());
}

堆栈追踪:

at System.IO.MemoryStream.set_Capacity(Int32 value)
at System.IO.MemoryStream.EnsureCapacity(Int32 value)
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.Xml.XmlUtf8RawTextWriter.FlushBuffer()
at System.Xml.XmlUtf8RawTextWriter.RawText(Char* pSrcBegin, Char* pSrcEnd)
at System.Xml.XmlUtf8RawTextWriter.RawText(String s)
at System.Xml.XmlUtf8RawTextWriter.WriteFullEndElement(String prefix, String localName, String ns)
at System.Xml.XmlUtf8RawTextWriterIndent.WriteFullEndElement(String prefix, String localName, String ns)
at System.Xml.XmlWellFormedWriter.WriteFullEndElement()
at System.Xml.XmlElement.WriteTo(XmlWriter w)
at System.Xml.XmlElement.WriteContentTo(XmlWriter w)
at System.Xml.XmlElement.WriteTo(XmlWriter w)
at System.Xml.XmlElement.WriteContentTo(XmlWriter w)
at System.Xml.XmlElement.WriteTo(XmlWriter w)
at System.Xml.XmlElement.WriteContentTo(XmlWriter w)
at System.Xml.XmlElement.WriteTo(XmlWriter w)
at System.Xml.XmlElement.WriteContentTo(XmlWriter w)
at System.Xml.XmlElement.WriteTo(XmlWriter w)
at System.Xml.XmlElement.WriteContentTo(XmlWriter w)
at System.Xml.XmlElement.WriteTo(XmlWriter w)
at System.Xml.XmlDocument.Save(XmlWriter w)

2 个答案:

答案 0 :(得分:1)

也许在关闭流之前尝试返回你的字符串,“using”语句在这里可以提供帮助。 这似乎适用于5MB xml文件。

  public static string BeautifyXmlDocument(XmlDocument doc)
        {
            using (MemoryStream sb = new MemoryStream())
            {
                XmlWriterSettings s = new XmlWriterSettings();
                s.Indent = true;
                s.IndentChars = "  ";
                s.NewLineChars = "\r\n";
                s.NewLineHandling = NewLineHandling.Replace;
                s.Encoding = new UTF8Encoding(false);
                using (XmlWriter writer = XmlWriter.Create(sb, s))
                {
                    doc.Save(writer);
                    return Encoding.UTF8.GetString(sb.ToArray());
                }
            }
        }

答案 1 :(得分:1)

只要您的实施需要获取文档的完整字符串,就可以创建导致XmlDocument的{​​{1}}。要真的解决这个问题,你需要转向使用OutOfMemoryException个对象(例如任何Stream),这样只有一小部分文档可以真正存在任何给定时间的记忆。如果您提供有关如何使用美化字符串的更多详细信息,我或其他人可能会想出一些可以提供帮助的内容。

另一方面,如果您无法更改实施以避免将整个字符串存储在内存中,则应更改已发布的实施以使用TextWriter并将其传递给StringWriter 。这至少消除了一些内存压力,因为你不会同时在内存中XmlWriter.Create 最后MemoryStream

string