在C#中合并大文件
我有7-8个xml文件。每个文件的大小约为50 MB。在不获取System.OutOfMemory异常的情况下,在C中以编程方式合并文件的最佳方法是什么?到目前为止,我尝试读取StringBuilder中的每个文件,而不是将其放入字符串生成器数组中,但是我仍然遇到system.outofmemoery异常。有帮助吗?
谢谢,
-尼姆什
解决方案
关于stringbuilder的事情是,我们仍在尝试将所有内容保留在内存中。我们一次只想保留一小部分内存,这意味着使用文件流。不要将整个文件读到内存中,不要在其上打开流,并继续从该流中读取数据。
xml的问题在于我们不能仅将它们彼此添加:我们将破坏标签嵌套。因此,我们需要了解有关xml文件结构的一些知识,以便我们对每个文件边界处的处理方法有所了解。
如果我们有某种理论上可以与StringBuilder一起使用的东西,但是由于内存限制而只能在实践中失败,那么我们应该能够将StringBuilder的.Append()和.AppendLine()方法调用转换为.Write()和.WriteLine()要求一个文件流。
这取决于合并的含义,因为我们尚未发布有关架构的任何信息。
在单个集合中同构简单元素的最简单情况下,我们将直接合并到磁盘上的新文件中,避免进行大量内存工作,从而确保将外部包含的元素剥离并添加到集合周围。
不确定在这种情况下合并意味着什么。我们是指文件的简单串联,还是要检查内容?
例如,
file1.xml
<items> <item id="1"> <name>Widget</name> </item> <item id="2"> <name>Widget 2</name> </item> </items>
file2.xml
<items> <item id="3"> <name>Widget</name> </item> <item id="4"> <name>Widget 2</name> </item> </items>
可以合并为
<items> <item id="1"> <name>Widget</name> </item> <item id="2"> <name>Widget 2</name> </item> </items> <items> <item id="3"> <name>Widget</name> </item> <item id="4"> <name>Widget 2</name> </item> </items>
这是非常琐碎的,或者
<items> <item id="1"> <name>Widget</name> </item> <item id="2"> <name>Widget 2</name> </item> <item id="3"> <name>Widget</name> </item> <item id="4"> <name>Widget 2</name> </item> </items>
鉴于我们正在谈论的数据量,事实并非如此。你是什么意思
请定义"合并"。
如果只想串联文件,则使用StreamReader,并逐行读取。
如果我们实际上想产生一个新的有效xml,请使用XmlTextReader。它不会读取内存中的整个文件。
我们需要合并的细节的确至关重要。但是,首先要开始:我们可能希望每个输入文件都使用XmlReader,而输出文件则需要XmlWriter。这样一来,我们就可以流式传输输入和输出。
另一种选择是使用从LINQ到XML的XStreamingElement。我对此没有任何经验,但它可能是使用起来更简单的API。 (LINQ to XML的其余部分肯定比DOM API更好。)
通过调用" copy a.xml + b.xml"命令或者通过" copy"命令使用的Windows文件系统API将它们合并到文件系统中。
就个人而言,当我不得不处理XML文件(通常是受到人身暴力威胁时)时,我会这样做:
- 通过DataSet.ReadXML()将每个文件加载到.NET DataSet中
- 合并信息(通过数据集查询)。
- 通过DataSet.WriteXML()将组合的DataSet写出为XML
然后,我积极删除原始XML文件并擦除磁盘上存在的原始扇区以删除污点。 :-)