XmlDocument::Save()函数将xml追加到文件中。

7
我希望在一个类中保留一个单一的XmlDocument对象,并让方法对其进行更改和保存。
using (FileStream fs = new FileStream(@"D:\Diary.xml", 
       FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
{
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load(fs);

    // ... make some changes here

    xmlDoc.Save(fs);
}

上述代码在文件内部复制了两份xml结构。

为什么你要使用FileStream,而不是直接指定文件路径进行加载呢?我认为文件访问的默认行为就是你所指定的。 - Dave
XML文件在不同的模块之间共享,这些模块只读取它(不写入)。我想在此模块中打开/读取并锁定以进行写入。 - A9S6
4个回答

4

尝试

fs.SetLength(0);

保存之前的调用


@IanR.O'Brien 这是因为他正在使用相同的文件流来加载文件(因此在加载后,位置位于文件末尾)。但是你想要做的是,在再次写出XML之前截断流中已有的内容。 - Michal Ciechan

2

添加:

fs.Position = 0;

在保存之前。


我尝试过了,但它的行为非常奇怪。一些数据被覆盖了,整个文件现在不再是一个有效的XML文件。 - A9S6

0

看起来Foole方案中的fs.Position无法正常工作,有点奇怪。

一个等价的解决方案是

fs.Seek(0, SeekOrigin.Begin);

或者

不使用相同的文件流:

            //OrigPath is the path you're using for the FileReader

            System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(OrigPath);
            xmlDoc.Save(writer);
            writer.Close();

2
它不会起作用,因为如果原始的XML文件长度为1000个字符,在更改xmldocument后,它只包含600个字符,你最终将得到正确的XML文件末尾剩余的400个字符未被删除。这就是为什么会出现验证错误的原因,例如:原始: <test><book1></book1></test>你将xmldocument更改为<test><a></a></test>你最终将得到 <test><a></a></test>></test>请注意末尾不必要的"></test>"。 - Michal Ciechan
没错!支持 @LnDCobra 的评论。 - A9S6

0

或者甚至这个也可以运行...

        XmlDocument xmlDoc = new XmlDocument( );
        xmlDoc.Load( @"D:\Diary.xml" );

        //.... make some changes here
        XmlText node = xmlDoc.CreateTextNode( "test" );
        xmlDoc.DocumentElement.AppendChild( node );

        xmlDoc.Save( @"D:\Diary.xml" );

这可能有效,但我认为将长度设置为零并调用保存会更加高效。 - A9S6
这样做不行,因为文件在那个时候正在使用,所以我永远无法保存该文件。 - Willem T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接