我有一段适用于普通文件的代码。但对于非常大的文件,它会使服务器停止工作。
这是:
XmlReader reader = null;
try
{
reader = XmlReader.Create(file_name + ".xml");
XDocument xml = XDocument.Load(reader);
XmlNamespaceManager namespaceManager = GetNamespaceManager(reader);
XElement root = xml.Root;
//XAttribute supplier = root.XPathSelectElement("//sh:Receive/sh:Id", namespaceManager).Attribute("Authority");
//string version = root.XPathSelectElement("//sh:DocumentId/sh:Version", namespaceManager).Value;
var nodes = root.XPathSelectElements("//eanucc:msg/eanucc:transact", namespaceManager);
return nodes;
}
catch
{ }
我认为这是导致服务器上发生内存问题的部分。我该如何解决这个问题?
答案 0 :(得分:3)
听起来好像只有太多的数据可以一次读取。您必须一次迭代一个元素,使用XmlReader
作为游标,并一次将一个元素转换为XElement
。
public static IEnumerable<XElement> ReadTransactions()
{
using (var reader = XmlReader.Create(file_name + ".xml"))
{
while (reader.ReadToFollowing("transact", eanuccNamespaceUri))
{
using (var subtree = reader.ReadSubtree())
{
yield return XElement.Load(subtree);
}
}
}
}
注意:这假设在任何其他级别都没有“transact”元素。如果有,您需要更加谨慎对待XmlReader
,而不仅仅是致电ReadToFollowing
。另请注意,您需要找到eanucc
别名的实际名称空间URI。
不要忘记,如果您尝试一次性阅读所有此信息(例如通过调用ToList()
),那么您仍然会耗尽内存。您需要流式传输信息。 (目前还不清楚你要对这些元素做些什么,但你需要仔细考虑它。)
答案 1 :(得分:0)
尝试将阅读器放入using(){}子句中,以便在使用后将其处理掉。
try
{
using(var reader = XmlReader.Create(file_name + ".xml"))
{
XDocument xml = XDocument.Load(reader);
XmlNamespaceManager namespaceManager = GetNamespaceManager(reader);
XElement root = xml.Root;
var nodes = root.XPathSelectElements("//eanucc:msg/eanucc:transact", namespaceManager);
return nodes;
}
}
catch
{ }