Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 就地修改XML文件?_C#_.net_Xml_File Handling - Fatal编程技术网

C# 就地修改XML文件?

C# 就地修改XML文件?,c#,.net,xml,file-handling,C#,.net,Xml,File Handling,假设我有以下XML文件: <book> <name>sometext</name> <name>sometext</name> <name>sometext</name> <name>Dometext</name> <name>sometext</name> </book> 一些文字 一些文字 一些文字 圆顶文字 一些文字 如果我想通过

假设我有以下XML文件:

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

一些文字
一些文字
一些文字
圆顶文字
一些文字

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

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

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

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

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

您需要
查找文件中要更改的位置,然后
将该字符写入磁盘

在.NET世界中,使用
FileStream
对象,您需要将
Position
属性设置为
D
字符的索引,然后编写单个
s
字符

请阅读以下问题:。看起来您不能真正使用
FileStream
对象,而是必须编写单个字节


祝你好运。但实际上,如果我们只讨论10MB,那么就把它弄脏。计算机应该正在执行您的工作。

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

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

因为长度可能会发生变化,所以在第一次更换之后,您至少必须移动所有东西。多次替换的可能性意味着您可能需要一个大的缓冲区来适应更改


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

我只需要读入文件,处理,然后把它吐出来

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

  • 打开文件输入文件流(XmlReader)
  • 打开输出文件流(XmlWriter,到另一个文件)
  • 从XmlReader读取数据,然后写入XmlWriter,执行任何必要的转换
  • 合流
  • 将新文件移到旧文件(覆盖,原子操作)
  • 虽然这可以设置为在同一个打开的文件上处理输入和输出,但使用一堆非常巧妙的工作,不会保存任何内容,并且存在许多边缘情况,包括文件长度增加或减少。事实上,尝试简单地向后移动文件内容以填补空白或向前移动文件内容以腾出新空间可能会更慢。除了最基本的长度保持操作外,文件系统缓存可能会使任何“收益”最小化/没有意义。此外,就地修改文件不是一个原子操作,并且在发生错误时通常是不可恢复的:以临时文件为代价,读/写/移动方法是原子操作,而不是最终的文件内容

    <>或者,考虑它是为这个设计的);
    愉快的编码。

    您所有的编辑都保留长度吗?@Henk无法理解此处保留长度的含义:(您的示例将1个字符替换为1个其他字符。这是可行的。但是将
    Dometext
    更改为
    SomeString
    是一个完全不同的问题。@Abhishek Gupta认为编辑不会增加(或减少)长度(以字节为单位)的XML文件。特别是,编辑不会影响小隔离区域之外的长度——将“Dometext”替换为“sometext”将保留长度,同时将“Dometext”替换为“Hello world!”不。否替换文本可以是任意长度的,即使我们可能还需要删除整个特定节点如何使用XmlDocument对象进行操作。因此,我们不需要重写整个文件:),因为我的XMl文件大小超过10 MB,我不想仅仅因为更改了一个字符而重写它:)“而不必读/写整个文件”。当你阅读所有内容时,你最好将其加载到XDocument中。@Abhishek Gupta 1)用“简单的方法”做它2)对它进行基准测试3)如果#2显示它太慢(需要定义一个功能需求;-),就用“困难的方法”做它——程序员的时间也很重要;-)现代计算机的10MB容量(通常)算不了什么。要使用XmlDocument,您需要重写整个文件。如果您正在处理磁盘上的文件,这可能会有所帮助: