在C#中,有没有办法将XML节点添加到磁盘上的文件而不先加载它?

我在磁盘上有一个非常基本的XML结构/文件,它类似于:

 kdkdkdk kdkdkdkgffgfdgf kddsdsfsdkdkdk  

如上所述,XML将位于磁盘上的外部文件中。 由于文件可能会变得相当大(实际上每隔几周会被“修剪”),我不想先加载XML文件来添加新节点……

有没有办法添加这样的新节点? 它可以被添加到顶部/底部等,因为实际使用XML的进程无论如何都按时间戳对它进行排序。

我猜测粗略的方法是将节点作为文本附加..但是我认为这会在结束标记之后添加节点?

任何想法都感激不尽……大卫。

这里有很多不错的答案,但只是为了对此进行另一次调整,你确定这些数据需要存储为XML文件吗?

您存储的数据看起来相当简单(即包含三个字段,日期,类型和一些字符串数据的记录。如果您不需要XML提供的任何附加好处( 请参阅此处 ),那么为什么不使用基本的CSV?你可以通过File.AppendText("filename")将日志文件添加到日志文件中。

(天啊,甚至可以使用像log4net这样的东西来管理日志记录和任何清理管理。)

不使用任何XML API或工具。

您可以将文件作为文本打开,找到的位置并从那里开始覆盖。 当然,再次添加


一种快速而肮脏的方法,这不是很强大:

  • 确保准备初始文件,结束标记后应该没有任何内容 (没有空格)
  • 确保使用ASCII或UTF8编码

====

 string closeTag = ""; int closeLength = Encoding.UTF8.GetBytes(closeTag).Length; var fs = System.IO.File.Open(filename, System.IO.FileMode.Open); fs.Position = fs.Length - closeLength; var writer = new StreamWriter(fs); // after the Position is set writer.WriteLine(newTag); writer.Write(closeTag); // NOT WriteLine !! writer.Close(); fs.Close(); 

当然,您知道使用using() {}块。

不知何故,您必须阅读XML文件,因为您不能只是在文档中添加节点。

Xml文件只能有一个根,因此必须在最后一个数据元素之后添加新节点,但是必须在根结束标记之前添加。 否则xml无效。

要看。

如果您想以“正确”的方式执行此操作,则必须读取文件及其中的XML。 例如,您可以通过使用XmlReader类来避免将其完全加载到内存中。

但是,如果你绝对知道文本的布局和文件的编码,你可以通过打开它作为随机访问文件(FileStream)来避免完全读取和重写它,跳到最后(减去““),在那里添加新条目并再次写入”“。

在没有阅读完整文件的情况下,我无法看到一种方法来做你正在做的事情,但作为一种解决方法,你可以将文件视为纯文本,即没有根节点(它将是无效的XML)。 然后,您可以将新节点作为纯文本添加到文件中。 而且,由于您的XML解析过程无论如何都会加载整个文件,因此它可以在将根节点视为XML之前添加它。

 System.IO.FileInfo[] aryFi = di.GetFiles("*.xml"); foreach (System.IO.FileInfo fi in aryFi) { System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument(); xmlDocument.Load(fi.FullName); XmlNode refelem = xmlDocument.LastChild; XmlNode newElem = xmlDocument.CreateNode("element", "something", ""); newElem.InnerText = "sometext"; xmlDocument.InsertAfter(newElem, refelem); } 

我相信打开和插入节点是最好的选择。 无论哪种方式,你都需要使用IO,为什么不采用正确的方法呢?

对于单个文件

 System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument(); xmlDocument.Load("file path"); XmlNode refelem = xmlDocument.LastChild; XmlNode newElem = xmlDocument.CreateNode("element", "something", ""); newElem.InnerText = "sometext"; xmlDocument.InsertAfter(newElem, refelem); 

如果不加载XML,则意味着不构建DOM树,VTD-XML是唯一允许您逐步剪切粘贴拆分或修改的API。 此外,由于VTD-XML具有内存效率,因此您不必担心XML文档的大小。 Java中的类似post是如何更新大型XML文件 。 请注意,vtd-xml在Java,C#,C和C ++中可用。

只是用

 string s = File.ReadAllText(path) s = s.replace("", newnode + "") File.WriteAllText(s, path)