Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# XmlDocument.Save OutOfMemory异常_C#_Xml_Xmldocument - Fatal编程技术网

C# XmlDocument.Save OutOfMemory异常

C# XmlDocument.Save OutOfMemory异常,c#,xml,xmldocument,C#,Xml,Xmldocument,我一直在使用这个方便的函数来“美化”xml文档,使其具有缩进和换行格式。但是对于更大的文档(~1MB),出于某种原因,我在doc.Save(writer)上遇到了OutOfMemoryException。如何解决此问题 public static string BeautifyXmlDocument(XmlDocument doc) { MemoryStream sb = new MemoryStream(); XmlWriterSettings s = new XmlWrite

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

也许在关闭流之前尝试返回字符串,“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());
                }
            }
        }

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

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

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

我尝试了你的函数和上面的函数,但它们都给出了OutOfMemoryException。在函数中,sw.ToString()现在给出内存错误。我没有提到的一件事是,我的程序将大约1.5GB的数据加载到内存中。所以,我怀疑这可能会对事情产生影响。XML只是一个配置文件,我用其他参数保存数据的文件名位置。我可以直接将配置序列化为XML文件,但人们希望查看它并用文本编辑器修改它,所以我需要先美化它。除非XML文档很大(我个人发现加载到
XmlDocument
中的文件大约为125兆,地址空间为2千兆位),我会考虑减少其他领域的内存使用。这可能是打破骆驼背的稻草。至于在GUI上显示它,呃,我没有答案。我想知道一种节省内存的方法来实现这一点。