3

我一直在使用这个方便的功能来“美化”一个 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)
4

2 回答 2

1

也许在关闭流之前尝试返回你的字符串,“使用”语句可以在这里提供帮助。这似乎适用于 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());
                }
            }
        }
于 2012-11-24T22:04:16.490 回答
1

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

另一方面,如果您无法更改实现以避免将整个字符串保存在内存中,则应将发布的实现更改为使用 aStringWriter并将其传递给XmlWriter.Create。这至少消除了一些内存压力,因为您不会同时在内存中拥有 theMemoryStream final string

public static string BeautifyXmlDocument(XmlDocument doc)
{
    using (StringWriter sw = new StringWriter())
    {
        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(sw, s))
        {
            doc.Save(writer);
        }
        return sw.ToString();
    }
}
于 2012-11-24T22:12:40.180 回答