【发布时间】:2020-12-13 17:28:42
【问题描述】:
我正在使用 XmlReader.ReadInnerXml() 加载部分 XML 文件并将其保存为 XmlDocument。当 innerXml 部分超过 2 GB(估计值)时,我遇到了 OutOfMemoryException。处理此错误的最佳方法是什么?有没有更好的方法从 XmlReader 创建一个大的 xml?我可以在不加载到内存的情况下保存内容吗?
using (XmlReader xmlRdr = XmlReader.Create(file))
{
xmlRdr.MoveToContent();
while (xmlRdr.Read())
{
//when read to XmlNodeType.Element and xmlRdr.Name meets certain criteria
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
try
{
xmlDoc.LoadXml(xmlRdr.ReadInnerXml());
//get a few data from within the innerXml and eventually use XmlWritter to save the file
}
catch(Exception e)
{
string content = $"{e.GetType()} {e.Message} {NewLine} {objId}";
//send content to log file and email
}
}
}
【问题讨论】:
-
与其将那个巨大的文件加载到内存中,为什么不使用流并从那里读取呢?
-
我需要从该 innerXml 中获取一些数据,并最终将该 innerXml 部分保存为 xml 文件。然后,将读取推进到下一个 innerXml 的下一个节点。
-
嗯,它不会改变任何东西。您可以从流中读取文件,进行更改,然后将其写入文件。 Here's an example
-
您可以使用
XmlReader.ReadSubtree()直接读取XML 文件的范围部分,而无需调用ReadInnerXml()将整个部分转换为字符串。它对应于ReadOuterXml()返回的XML,因此您需要先使用ReadStartElement()使用外部元素,然后再将其传递给xmlDoc.Load(subRdr)。请参阅dotnetfiddle.net/Z7S1pT 和 ReadOuterXml is throwing OutOfMemoryException reading part of large (1 GB) XML file 和 XmlReader read continually。 -
这应该可以节省大量内存,并且可以回答您的问题。但如果没有,请查看Automating replacing tables from external files 和Combining the XmlReader and XmlWriter classes for simple streaming transformations,并使用minimal reproducible example 更新您的问题。
标签: c# out-of-memory xmldocument xmlreader