我有一个大的xml文件(大约10 MB)以下简单的结构:
<Errors>
<Error>.......</Error>
<Error>.......</Error>
<Error>.......</Error>
<Error>.......</Error>
<Error>.......</Error>
</Errors>
Run Code Online (Sandbox Code Playgroud)
我需要在</ Errors>标记之前的末尾添加一个新节点<Error>.什么是在.net中实现这一目标的最快方法?
tof*_*fi9 10
您需要使用XML包含技术.
你的error.xml(不会改变,只是一个存根.由XML解析器用来读取):
<?xml version="1.0"?>
<!DOCTYPE logfile [
<!ENTITY logrows
SYSTEM "errorrows.txt">
]>
<Errors>
&logrows;
</Errors>
Run Code Online (Sandbox Code Playgroud)
你的errorsrows.txt文件(更改,xml解析器不理解它):
<Error>....</Error>
<Error>....</Error>
<Error>....</Error>
Run Code Online (Sandbox Code Playgroud)
然后,向errorsrows.txt添加一个条目:
using (StreamWriter sw = File.AppendText("logerrors.txt"))
{
XmlTextWriter xtw = new XmlTextWriter(sw);
xtw.WriteStartElement("Error");
// ... write error messge here
xtw.Close();
}
Run Code Online (Sandbox Code Playgroud)
或者您甚至可以使用.NET 3.5 XElement,并将文本追加到StreamWriter:
using (StreamWriter sw = File.AppendText("logerrors.txt"))
{
XElement element = new XElement("Error");
// ... write error messge here
sw.WriteLine(element.ToString());
}
Run Code Online (Sandbox Code Playgroud)
另请参阅Microsoft的文章修改大型XML文件的高效技术
首先,我将取消对System.Xml.XmlDocument的限制,因为它是一个DOM,它需要在可以附加到内存之前解析并构建内存中的整个树.这意味着您的10 MB文本内存将超过10 MB.这意味着它是"内存密集型"和"耗时".
其次,我会取消System.Xml.XmlReader的资格,因为它需要先解析整个文件,然后才能到达可以附加到它的位置.您必须将XmlReader复制到XmlWriter中,因为您无法修改它.这需要先在内存中复制XML,然后才能附加到它.
XmlDocument和XmlReader的更快解决方案是字符串操作(它有自己的内存问题):
string xml = @"<Errors><error />...<error /></Errors>";
int idx = xml.LastIndexOf("</Errors>");
xml = xml.Substring(0, idx) + "<error>new error</error></Errors>";
Run Code Online (Sandbox Code Playgroud)
切掉结束标记,添加新错误,然后添加结束标记.
我想你可能会对此发疯,并将你的文件截断9个字符并附加到它上面.不必读取文件并让操作系统优化页面加载(只需加载最后一个块或其他东西).
System.IO.FileStream fs = System.IO.File.Open("log.xml", System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite);
fs.Seek(-("</Errors>".Length), System.IO.SeekOrigin.End);
fs.Write("<error>new error</error></Errors>");
fs.Close();
Run Code Online (Sandbox Code Playgroud)
如果您的文件为空或仅包含"<错误> </错误>",则会出现问题,通过检查长度可以轻松处理这两个问题.