处理大型xml文件
看到《修改大型 XML 文件的有效方法》http://www.microsoft.com/china/MSDN/library/data/xml/largexml.mspx这篇文章已经有一段时间了,今天终于腾出手来试了试。
都知道XmlDocument装载一个xml文件是将所有内容一下子load进来的,遇到很大的xml文件,问题就很大,曾经我load一个3mb的文件,调试时能明显感觉到消耗的时间。XmlReader好,据说XmlReader只是使用几十K(?)的内存,顺序读进来的,可是是只读的。
msdn这篇文章就是讲如何用XmlReader和XmlWriter来处理大型xml文件的。我写了如下的代码测试了一下,中间省去了一些这篇文章使用的XmlNameTable和XmlValidatingReader等。
这个是用XmlReader和XmlWriter处理
private void button1_Click(object sender, System.EventArgs e)
{
System.Diagnostics.Debug.WriteLine(System.DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());
File.Copy("ResourceList.xml", "Temp.xml", true); // 因为要更新,先copy一个副本
XmlTextReader reader = new XmlTextReader("Temp.xml");
reader.WhitespaceHandling = WhitespaceHandling.Significant;
reader.MoveToContent();
StreamWriter sw = new StreamWriter("ResourceList.xml", false, System.Text.Encoding.UTF8); // 创建writer
XmlWriter xw = new XmlTextWriter(sw);
xw.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
reader.Read();
do
{
if(reader.Name == "RESOURCE")
xw.WriteStartElement("RESOURCE");
else if(reader.Name == "CTNO")
xw.WriteElementString("CTNO", reader.ReadString());
else if(reader.Name == "ITMNUM")
xw.WriteElementString("ITMNUM", reader.ReadString());
else if(reader.Name == "RESTYP")
xw.WriteElementString("RESTYP", reader.ReadString());
else if(reader.Name == "RESNAM")
{
if(reader.ReadString().Equals("I99000000001")) // 这里做比较,并替换内容
xw.WriteElementString("RESNAM", "Hello");
else
xw.WriteElementString("RESNAM", reader.ReadString());
}
reader.Read();
if(reader.Name == "RESOURCE")
{
if(reader.NodeType == XmlNodeType.EndElement)
{
xw.WriteEndElement();
reader.Read();
}
}
}while(reader.NodeType == XmlNodeType.Element);
xw.Close();
reader.Close();
System.Diagnostics.Debug.WriteLine(System.DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());
}
下面是用XmlDocument来处理这个文件
private void button2_Click(object sender, System.EventArgs e)
{
System.Diagnostics.Debug.WriteLine(System.DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());
XmlDocument domTemp = new XmlDocument();
domTemp.Load("ResourceList.xml");
XmlNode node = domTemp.SelectSingleNode("descendant::RESOURCE[RESNAM='I99000000001']");
if(node != null)
{
node.SelectSingleNode("RESNAM").InnerText = "Hello";
}
else
{
node = domTemp.SelectSingleNode("descendant::RESOURCE[RESNAM='Hello']");
if(node != null)
node.SelectSingleNode("RESNAM").InnerText = "I99000000001";
}
domTemp.Save("ResourceList.xml");
System.Diagnostics.Debug.WriteLine(System.DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());
}
我的测试用.net framework 1.1,xml文件大小808KB。
执行结果:
内存消耗:因为我不怎么会用CLR Profiler,不会分析 , 按理说肯定会有不同
执行时间:用xmlreader+xmlwriter,耗时370ms; 用xmlDocument耗时391ms