Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.NET中处理大型XML文件_C#_Xml_Serialization_Bigdata - Fatal编程技术网

C# 在.NET中处理大型XML文件

C# 在.NET中处理大型XML文件,c#,xml,serialization,bigdata,C#,Xml,Serialization,Bigdata,我想反序列化XML文件,对其内容进行一些转换,然后将其序列化回另一个文件。问题是,我想要反序列化的XML文件有200 GB的数据。显然,我无法将所有内容反序列化到内存中。我要做的是反序列化、转换和序列化数据块。XML模式非常简单: <root> <node> <title>SomeNodeTitle1</title> <text>Some Node Text 1. A lot of Text.&l

我想反序列化XML文件,对其内容进行一些转换,然后将其序列化回另一个文件。问题是,我想要反序列化的XML文件有200 GB的数据。显然,我无法将所有内容反序列化到内存中。我要做的是反序列化、转换和序列化数据块。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>
因为读取这么大的文件时会抛出异常


我能做些什么,我能用什么使块读、转换、写成为可能?

您需要手动执行一些工作。 您可以分块读取文件(尝试生成块)≈x2典型节点的尺寸(如果可能)。

while(hasSomethingToDo)
{   
而(!StringBuffer.Contains(“”)
{
StringBuffer+=ReadStringFromOutput(bufferSize:2*典型节点大小)
}
while(StringBuffer.Contains(“”)//若节点较大,则应在此处进行优化
{
CutStringBuffer(切出的部分、切出的剩余部分,“,”);
XmlSerializer serializer=新的XmlSerializer(typeof(Node));
使用(变量读取器=新StreamReader(cuttedPart))
{
节点=(节点)序列化程序。反序列化(读取器);
节点=转换节点(节点);
写输出(节点);
}
StringBuffer=剩余;
}
}

另一个选项是使用

首先枚举所有记录并创建一个静态缓冲区,例如1000条记录或您需要的记录。然后将所需记录迭代到缓冲区中,转换到被调用方并释放缓冲区内容,或使用新的缓冲区内容替换/更新缓冲区内容。是否可以选择使用流@马文·斯密特:是的。所有符合预期目的的内容都是一个选项。您确定要/需要反序列化吗?描述中没有这样的要求,一种非常有效的方法是应用XSL。否则:使用XmlReader和XmlWriter,并在两者之间执行逻辑。此外,还应删除标记前的空白,并在XML模式与预期不匹配时输出错误或警告。
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();
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;
  }
}