在.net中处理大型XML文件

本文关键字:XML 文件 大型 处理 net | 更新日期: 2023-09-27 18:01:38

我想对XML文件进行反序列化,对其内容进行一些转换,然后将其序列化回另一个文件。问题是,我要反序列化的XML文件有200gb的数据。很明显,我无法将它们全部反序列化到记忆中。我要做的,是对数据块进行反序列化,转换和序列化。XML模式非常直接:

<root>
    <node>
        <title>SomeNodeTitle1</title>
        <text>Some Node Text 1. A lot of Text.</text>
    </node>
    <node>
        <title>SomeNodeTitle2</title>
        <text>Some Node Text 2. A lot of Text.</text>
    </node>
    <node>
        <title>SomeNodeTitle3</title>
        <text>Some Node Text 3. A lot of Text.</text>
    </node>
    <node>
        <title>SomeNodeTitle4</title>
        <text>Some Node Text 4. A lot of Text.</text>
    </node>
</root>

我想(或多或少)这样做:

OpenInputFile();
OpenOutputFile(); // Write root node tag
while(there_are_any_unprocessed_nodes_in_file)
{
    List<Node> nodes = TakeNodeChunk();
    Transform(nodes); // Let's say remove all "cat" word occurences in text
    AppendNodesToOutputXmlFile(nodes);
}
CloseInputFile();
CloseOutputFile(); // Close root node tag

显然我不能使用这种结构:

XmlSerializer serializer = new XmlSerializer(typeof(Root));
StreamReader reader = new StreamReader(filePath);
Root root = (Root)serializer.Deserialize(reader);
reader.Close();

因为读取这么大的文件会抛出异常。

我能做些什么呢,我能用什么让chunk readtransformwrite成为可能呢?

在.net中处理大型XML文件

您将需要手动执行一些工作。您可以以块的形式从文件中读取(如果可能的话,尝试使块≈典型节点的x2大小)。

while (hasSomethingToDo)
{   
  while (!StringBuffer.Contains("</node>"))
  {
    StringBuffer += ReadStringFromOutput (bufferSize: 2*TYPICAL_NODE_SIZE)
  }
  while (StringBuffer.Contains("</node>")) //if node is large, you should optimize here
  {
    CutStringBuffer(out cuttedPart, out leftover, "<node>", "</node>");
    XmlSerializer serializer = new XmlSerializer(typeof(Node));
    using (var reader = new StreamReader(cuttedPart))
    {
      Node node = (Node)serializer.Deserialize(reader);
      node = TransformNode(node);
     WriteToOuput(node);
    }
    StringBuffer = leftover;
  }
}

另一个选择是使用http://msdn.microsoft.com/library/system.xml.xmlnodereader.aspx