如何/我可以使用 linq to xml 以合理的内存消耗查询巨大的 xml 文件?

Posted

技术标签:

【中文标题】如何/我可以使用 linq to xml 以合理的内存消耗查询巨大的 xml 文件?【英文标题】:How/Can I use linq to xml to query huge xml files with reasonable memory consumption? 【发布时间】:2011-08-15 20:52:39 【问题描述】:

我对 linq to xml 做的不多,但我见过的所有示例都将整个 XML 文档加载到内存中。

如果 XML 文件大小为 8GB,而您真的没有选择权怎么办?

我的第一个想法是将XElement.Load Method (TextReader) 与FileStream Class 的实例结合使用。

问题:这是否可行,这是解决搜索非常大的 XML 文件问题的正确方法吗?

注意:不需要高性能..我正在尝试让 linq to xml 基本上完成我可以编写的程序的工作,该程序循环遍历我的大文件的每一行并收集起来,但由于 linq 是“以循环为中心”我希望这是可能的......

【问题讨论】:

【参考方案1】:

使用XElement.Load 会将整个文件加载到内存中。相反,使用 XmlReaderXNode.ReadFrom 函数,如果需要,您可以选择性地加载 XmlReaderXElement 找到的笔记以进行进一步处理。 MSDN 有一个很好的例子:http://msdn.microsoft.com/en-us/library/system.xml.linq.xnode.readfrom.aspx

如果你只需要搜索xml文档,单独XmlReader就足够了,不会将整个文档加载到内存中。

【讨论】:

【参考方案2】:

加布里埃尔,

伙计,这并不能完全回答您的实际问题(如何阅读大型 xml 文档使用 linq),但您可能想查看我的旧问题 What's the best way to parse big XML documents in C-Sharp。最后一个“答案”(按时间)是关于实际工作的“自我说明”。事实证明,混合文档-XmlReader 和 doclet-XmlSerializer 既快速(足够)又灵活。

但请注意,我处理的文档最多只有 150MB。如果您真的必须处理 8GB 大的文档?那我猜你可能会遇到各种各样的问题;包括 O/S 的 LARGE_FILE (>2GB) 处理问题...在这种情况下,我强烈建议您尽可能保持原始状态...并且 XmlReader 尽可能原始(并且根据我的测试是最快的) ) 在 Microsoft 命名空间中可用的 XML 解析器。

另外:我刚刚注意到我的旧帖子中有一条迟来的评论,建议我查看VTD-XML...我刚才快速浏览了一下...它“看起来很有希望”,即使作者似乎已经承包了FIGJAM的终端案件。他声称它将处理高达 256GB 的文档;我回答“是的,你测试过吗?在什么环境下?”听起来它应该可以工作......我已经使用相同的技术在文本帮助系统中实现“超链接”;回到 html 之前。

无论如何,祝你好运,以及你的整个项目。干杯。基思。

【讨论】:

我过去也成功使用过 XPathReader。 mvpxml.codeplex.com/… 这可能也值得评估..【参考方案3】:

我意识到这个答案可能被认为是无响应的并且可能很烦人,但我会说,如果你有一个 8GB 的​​ XML 文件,那么至少你在 XML 中尝试做的一些事情应该由文件系统或数据库。

如果您在该文件中有大量文本,您可以将它们存储为单独的文件,并分别存储元数据和文件名。如果你不这样做,你必须有很多层次的结构化数据,可能有很多重复的结构。如果您可以决定将什么视为单独的“记录”,可以将其存储为较小的 XML 文件或数据库的列中,那么您可以根据上面的嵌套级别来构建数据库。 XML 非常适合小而脏的数据,它也适合非结构化数据,因为它是自结构化的。但是,如果您有 8GB 的​​数据要做一些有意义的事情,那么您必须(通常)能够依赖其中某个地方的一些可预测的结构。

在数据库中存储 XML(或 JSON),查询和搜索 XML 记录,在 XML 中,现在 SQL 东西和 NoSQL 范式都很好地支持。

当然,您可能无法选择不使用这么大的 XML 文件,或者您可能在某些情况下它们确实是最佳解决方案。但对于一些阅读本文的人来说,看看这个替代方案可能会有所帮助。

【讨论】:

以上是关于如何/我可以使用 linq to xml 以合理的内存消耗查询巨大的 xml 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 linq-to-xml 查询简化此功能?

LINQ to XML - 从文件加载 XML 片段

如何使用 linq to xml 将列表保存在对象内?

如何使用 Linq to XML 将 HTML 保存在 XML 文件中?

LINQ-to-XML 中 XSD.EXE 的替代方案?

如何使用 LINQ to XML 获取属性值?