我想要一个最佳附加2个XML字符串的C#代码。它们都是相同的架构。我试过StreamReader / StreamWriter; File.WriteAllText; FileStream
我看到的问题是,它使用超过98%的物理内存,从而导致内存不足异常。
有没有一种方法可以在没有任何内存异常的情况下进行最佳合并?时间不是我关心的问题。
如果在内存中使用它将成为一个问题,那么还有什么可能更好?将其保存在文件系统上?
更多详情: 这是我的简单程序:提供更好的细节
static void Main(string[] args)
{
Program p = new Program();
XmlDocument x1 = new XmlDocument();
XmlDocument x2 = new XmlDocument();
x1.Load("C:\\XMLFiles\\1.xml");
x2.Load("C:\\XMLFiles\\2.xml");
List<string> files = new List<string>();
files.Add("C:\\XMLFiles\\1.xml");
files.Add("C:\\XMLFiles\\2.xml");
p.ConsolidateFiles(files, "C:\\XMLFiles\\Result.xml");
p.MergeFiles("C:\\XMLFiles\\Result.xml", x1.OuterXml, x2.OuterXml, "<Data>", "</Data>");
Console.ReadLine();
}
public void ConsolidateFiles(List<String> files, string outputFile)
{
var output = new StreamWriter(File.Open(outputFile, FileMode.Create));
output.WriteLine("<Data>");
foreach (var file in files)
{
var input = new StreamReader(File.Open(file, FileMode.Open));
string line;
while (!input.EndOfStream)
{
line = input.ReadLine();
if (!line.Contains("<Data>") &&
!line.Contains("</Data>"))
{
output.Write(line);
}
}
}
output.WriteLine("</Data>");
}
public void MergeFiles(string outputPath, string xmlState, string xmlFederal, string prefix, string suffix)
{
File.WriteAllText(outputPath, prefix);
File.AppendAllText(outputPath, xmlState);
File.AppendAllText(outputPath, xmlFederal);
File.AppendAllText(outputPath, suffix);
}
XML示例:
<Data> </Data>
附加在开头&amp;端
XML 1:<Sections> <Section></Section> </Sections>
XML 2:<Sections> <Section></Section> </Sections>
合并:<Data> <Sections> <Section></Section> </Sections> <Sections> <Section></Section> </Sections> </Data>
答案 0 :(得分:0)
试试这个,基于流的方法,避免一次将所有xml加载到内存中。
static void Main(string[] args)
{
List<string> files = new List<string>();
files.Add("C:\\XMLFiles\\1.xml");
files.Add("C:\\XMLFiles\\2.xml");
ConsolidateFiles(files, "C:\\XMLFiles\\Result.xml");
Console.ReadLine();
}
private static void ConsolidateFiles(List<String> files, string outputFile)
{
using (var output = new StreamWriter(outputFile))
{
output.WriteLine("<Data>");
foreach (var file in files)
{
using (var input = new StreamReader(file, FileMode.Open))
{
while (!input.EndOfStream)
{
string line = input.ReadLine();
if (!line.Contains("<Data>") &&
!line.Contains("</Data>"))
{
output.Write(line);
}
}
}
}
output.WriteLine("</Data>");
}
}
更好的方法是使用XmlReader(http://msdn.microsoft.com/en-us/library/system.xml.xmlreader(v=vs.90).aspx)。这将为您提供专门为xml设计的流阅读器,而不是用于阅读常规文本的StreamReader。
答案 1 :(得分:0)
看看here Teoman Soygul给出的答案似乎正是您所寻找的。 p>
答案 2 :(得分:0)
这是未经测试的,但我会使用TextReader和TextWriter在这些行上做一些事情。您不希望将所有XML文本读入内存或将其存储在字符串中,并且您不希望使用XElement / XDocument / etc.在中间的任何地方。
using (var writer = new XmlTextWriter("ResultFile.xml")
{
writer.WriteStartDocument();
writer.WriteStartElement("Data");
using (var reader = new XmlTextReader("XmlFile1.xml")
{
reader.Read();
while (reader.Read())
{
writer.WriteNode(reader, true);
}
}
using (var reader = new XmlTextReader("XmlFile2.xml")
{
reader.Read();
while (reader.Read())
{
writer.WriteNode(reader, true);
}
}
writer.WriteEndElement("Data");
}
再一次不能保证这个确切的代码可以按原样运行(或者它甚至可以编译),但我认为这是你正在寻找的想法。首先从File1流式传输数据并将其直接写入结果文件。然后,从File2流式传输数据并将其写出。在任何时候都不应该在内存中存储完整的XML文件。
答案 3 :(得分:-1)
你必须去文件系统,除非你有很多RAM 一个简单的方法:
File.WriteAllText("output.xml", "<Data>");
File.AppendAllText("output.xml", File.ReadAllText("xml1.xml"));
File.AppendAllText("output.xml", File.ReadAllText("xml2.xml"));
File.AppendAllText("output.xml", "</Data>");
另一:
var fNames = new[] { "xml1.xml", "xml2.xml" };
string line;
using (var writer = new StreamWriter("output.xml"))
{
writer.WriteLine("<Data>");
foreach (var fName in fNames)
{
using (var file = new System.IO.StreamReader(fName))
{
while ((line = file.ReadLine()) != null)
{
writer.WriteLine(line);
}
}
}
writer.WriteLine("</Data>");
}
所有这一切的前提是xml1.xml和xml2.xml中没有架构或标签 如果是这种情况,只需要省略它们的代码。