1

我有一段代码适用于普通文件。但是对于非常大的文件,它会使服务器停止工作。

这里是:

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
{ }

我认为这是导致服​​务器上发生内存问题的部分。我怎样才能解决这个问题?

4

2 回答 2

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

注意:这假设在任何其他级别都没有“交易”元素。如果有,您需要更加小心,XmlReader而不仅仅是调用ReadToFollowing. 另请注意,您需要找到eanucc别名的实际命名空间 URI。

不要忘记,如果您尝试一次性读取所有这些信息(例如通过调用ToList()),那么您仍然会耗尽内存。您需要流式传输信息。(目前尚不清楚您要对这些元素做什么,但您需要仔细考虑。)

于 2013-04-30T06:20:48.850 回答
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
{ } 
于 2013-04-30T05:59:38.573 回答