是否就地修改XML文件?

时间:2011-10-13 08:20:03

标签: c# .net xml file-handling

假设我有以下XML文件:

<book>
 <name>sometext</name>
 <name>sometext</name>
 <name>sometext</name>
 <name>Dometext</name>
 <name>sometext</name>
</book> 

如果我想通过将D更改为s来修改内容(如第四个“name”节点所示)而不必读/写整个文件,那么这可能吗?

4 个答案:

答案 0 :(得分:3)

10 MB的文件不是问题。啜饮它。修改DOM。将其写回文件系统。 10 GB更是一个问题。在那种情况下:

假设:您没有更改文件的长度。将文件视为字符数组而不是(链接)字符列表:您不能在中间添加字符,只能更改它们。

您需要seek文件中的位置进行更改,然后write将该字符更改为磁盘。

在.NET世界中,使用FileStream对象,您可以将Position属性设置为D字符的索引,然后编写单个s字符。 Check out this question on random access of text files

另请阅读此问题:How to insert characters to a file using C#。看起来你不能真正使用FileStream对象,而是必须求助于编写单个字节。

祝你好运。但实际上,如果我们只谈论10 MB,那么就把它搞砸了。计算机应该正在做你的工作。

答案 1 :(得分:2)

我只是阅读文件,处理并吐出来。

这可以使用XmlReader以流式方式完成 - 它比XmlDocument或XDocument更多的手动工作,但它确实避免创建内存中的DOM(XmlDocument / XDocument可以与此相同的读取/使用写模式,但通常需要在内存中完全重建):

  1. 打开文件输入文件流(XmlReader)
  2. 打开输出文件流(XmlWriter,到其他文件
  3. 从XmlReader中读取并写入XmlWriter,根据需要执行任何转换。
  4. 关闭溪流
  5. 将新文件移至旧文件(覆盖,原子操作)
  6. 虽然可以设置为在同一个打开的文件上处理输入和输出,并且有一堆非常聪明的工作但是不会保存任何内容,包括任何边缘情况,包括增加减少文件长度。实际上,可能更慢尝试简单地向后移动文件的内容以填补空白或向前移动文件内容以创建新的空间。除了最基本的长度保留操作之外,文件系统缓存可能会使任何“增益”最小/没有任何意义。此外,修改文件不是原子操作,并且在发生错误时通常是不可恢复的:以临时文件为代价,读/写/移动方法是原子wrt最终文件内容。

    或者,考虑XSLT - 它是为此设计的; - )

    快乐的编码。

答案 2 :(得分:1)

最干净(也是最好)的方法是使用XmlDocument对象进行操作,但快速而又脏的解决方案是将XML读取为字符串然后:

xmlText = xmlText.Replace("Dometext", "sometext");

答案 3 :(得分:1)

XML文件是文本文件,不允许插入/删除。支持的唯一突变是OverWrite和Append。与XML不太匹配。

所以,首先要确保你真的需要这个。这是一个复杂的操作,只值得在非常大的文件上。

由于长度可能会发生变化,因此您至少必须在第一次替换之后移动所有内容。多次替换的可能性意味着您可能需要一个大缓冲区来适应这些变化。

复制整个文件更容易。这在I / O中很昂贵,但可以节省内存使用。