XmlDocument.Load(String filename)和XmlDocument.Load(FileStream fs)之间的区别

Boo*_*oon 1 c# xml linq-to-xml

我已经尝试了一些关于将新子项添加到XML文件的代码.我注意到使用XmlDocument.Load(String filename)和XmlDocument.Load(FileStream fs)时结果不同.下面显示了原始XML文件数据.

<?xml version="1.0" encoding="utf-8"?>
<grandparent>
    <parent>
        <child>
            <grandchild>some text here</grandchild>
        </child>
        <child>
            <grandchild>another text here</grandchild>
        </child>
    </parent>
</grandparent>
Run Code Online (Sandbox Code Playgroud)

下面显示了使用XmlDocument.Load(String filename)附加子元素的C#代码

XmlDocument doc = new XmlDocument();
doc.Load(filename);

XmlNode child= doc.CreateNode(XmlNodeType.Element, "child", null);
XmlNode grandchild = doc.CreateNode(XmlNodeType.Element, "grandchild", null);
grandchild.InnerText = "different text here";
child.AppendChild(grandchild);
doc.SelectSingleNode("//grandparent/parent").AppendChild(child);
doc.Save(filename);
Run Code Online (Sandbox Code Playgroud)

结果XML文件正常工作,如下所示.

<?xml version="1.0" encoding="utf-8"?>
<grandparent>
    <parent>
        <child>
            <grandchild>some text here</grandchild>
        </child>
        <child>
            <grandchild>another text here</grandchild>
        </child>
        <child>
            <grandchild>different text here</grandchild>
        </child>
    </parent>
</grandparent>
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用XmlDocument.Load(FileStream fs),如下所示

FileStream fs = new FileStream(filename, FileMode.Open)
XmlDocument doc = new XmlDocument();
doc.Load(fs);

XmlNode child= doc.CreateNode(XmlNodeType.Element, "child", null);
XmlNode grandchild = doc.CreateNode(XmlNodeType.Element, "grandchild", null);
grandchild.InnerText = "different text";
child.AppendChild(grandchild);
doc.SelectSingleNode("//grandparent/parent").AppendChild(child);
doc.Save(fs);
fs.Close();
Run Code Online (Sandbox Code Playgroud)

结果XML文件将非常奇怪,就像重新复制整个XML文件一样,如下所示.

<?xml version="1.0" encoding="utf-8"?>
<grandparent>
    <parent>
        <child>
            <grandchild>some text here</grandchild>
        </child>
        <child>
            <grandchild>another text here</grandchild>
        </child>
    </parent>
</grandparent><?xml version="1.0" encoding="utf-8"?>
<grandparent>
    <parent>
        <child>
            <grandchild>some text here</grandchild>
        </child>
        <child>
            <grandchild>another text here</grandchild>
        </child>
        <child>
            <grandchild>different text here</grandchild>
        </child>
    </parent>
</grandparent>
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我为什么吗?提前致谢.

Xen*_*ing 5

调用XmlDocument.Save(FileStream fs)会将XmlDocument数据附加到流中.

之前在同一FileStream实例上调用的XmlDocument.Load(FileStream fs)将导致FileStream的位置被原始xml文件中的字节数偏移.因此,在此FileStream实例上执行的任何追加都将在读入数据之后.为了对此进行操作,您需要重置FileStream的位置.

要重置FileStream实例的位置,请使用:

... FileStream fs ...
... XmlDocument doc ...

fs.SetLength(0); //Optional: Clears the file on disk
fs.Flush(); //Optional: Flushes the stream to write the clear to disk
fs.Position = 0; //Resets the position of the stream
doc.Save(fs); //Save the XmlDocument to the FileStream
Run Code Online (Sandbox Code Playgroud)

编辑:两个FileStream方法.注意,在调用XmlDocument.Save之前,我已将FileMode更改为FileMode.Create; 这会创建一个全新的文件(清除文件的内容)

FileStream fs = null;
XmlDocument doc = new XmlDocument();

using (fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
    doc.Load(fs);
}

//Do stuff to the xmlDoc

using (fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
    doc.Save(fs);
}
Run Code Online (Sandbox Code Playgroud)