解析80gb的XML文件
本文关键字:文件 XML 80gb 解析 | 更新日期: 2023-09-27 18:04:15
我必须解析80gb的XML才能从该文件中获得一些数据。为此我使用了XML阅读器。当我检查代码与304 MB的文件。然后它在4秒内解析文件。所以我想我将为80 GB工作。但几分钟后,它却异常地给了我记忆。
我有以下代码:
static void Main(string[] args)
{
List<Test> lstTest = new List<Test>();
bool isTitle = false;
bool isText = false;
using (XmlReader Reader = XmlReader.Create(FilePath))
{
Test tt = new Test();
while (Reader.Read())
{ switch (Reader.NodeType)
{
case XmlNodeType.Element:
if (Reader.Name == "title")
{
isTitle = true;
}
if (Reader.Name == "text")
{
isText = true;
}
break;
case XmlNodeType.Text:
if (isTitle)
{
tt.Title = Reader.Value;
isTitle = false;
}
if (isText)
{
tt.Text = Reader.Value;
isText = false;
}
break;
}
if (tt.Text != null)
{
lstTest.Add(tt);
tt = new Test();
}
}
}
}
}
}
所以请建议。谢谢你的帮助。
你是对的,XmlReader
是正确的方法。这不是XmlReader
内存耗尽-这是你的lstTest
,你把你找到的大多数节点。
使用XmlReader
的正确方法是处理节点,然后忘记它们,继续前进。您可以将结果写入磁盘,或计算一些运行总数,或其他任何操作—但不要将读取的所有内容都保存在内存中—这违背了XmlReader
的目的。
您不应该将所有内容都存储到内存中,而应该只保留您感兴趣的部分。
这可以通过IEnumerable<>
和yield return
关键字来完成:
public IEnumerable<Test> ParseXml(string path)
{
bool isTitle = false;
bool isText = false;
using (XmlReader Reader = XmlReader.Create(FilePath))
{
Test tt = new Test();
while (Reader.Read())
{
switch (Reader.NodeType)
{
case XmlNodeType.Element:
if (Reader.Name == "title")
{
isTitle = true;
}
if (Reader.Name == "text")
{
isText = true;
}
break;
case XmlNodeType.Text:
if (isTitle)
{
tt.Title = Reader.Value;
isTitle = false;
}
if (isText)
{
tt.Text = Reader.Value;
isText = false;
}
break;
}
if (tt.Text != null)
{
yield return tt;
tt = new Test();
}
}
}
}
用法:
var data = ParseXml(/* your xml file */);
// select the part that you are interested in
var interestingTests = data
.Where(x => x.Title == "...")
foreach (var test in interestingTests)
{
// work with the interesting parts
}