Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.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# 通过StreamReader/StreamWriter打开和保存时,XmlDocument被篡改_C#_Xml_Winforms_.net 4.5_Filestream - Fatal编程技术网

C# 通过StreamReader/StreamWriter打开和保存时,XmlDocument被篡改

C# 通过StreamReader/StreamWriter打开和保存时,XmlDocument被篡改,c#,xml,winforms,.net-4.5,filestream,C#,Xml,Winforms,.net 4.5,Filestream,我有一个C语言的WinForms应用程序,它使用XML配置文件 为了防止其他应用程序和用户在应用程序运行时编辑这些文件,我使用 要打开文档,请执行以下操作: document = new XmlDocument(); using ( var xr = new StreamReader( new FileStream( fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read ), Encoding.UTF8 ) ) {

我有一个C语言的WinForms应用程序,它使用XML配置文件

为了防止其他应用程序和用户在应用程序运行时编辑这些文件,我使用

要打开文档,请执行以下操作:

document = new XmlDocument();

using ( var xr = new StreamReader( new FileStream( fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read ), Encoding.UTF8 ) )
{
    document.Load( xr );
}
…使用写入程序再次保存文件的Save()方法

lock ( syncLock )
{
    using ( var writer = XmlTextWriter.Create( new FileStream( fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read ), settings ) )
    {
        document.Save( writer );
    }
}
由于多个线程可能希望保存到该文件,因此存在锁。实际上,我不确定这是否有意义

当我从DOM树中删除一个节点,然后保存该文件时,该文件就变成了垃圾

这个漂亮的文件

<?xml version="1.0" encoding="utf-8"?>
<history>
  <period something="2013-01-01 04:55:12" added="2013-01-01 04:58:12" />
  <period something="2013-01-01 10:55:12" added="2013-01-01 10:58:12" />
  <period something="2013-01-01 16:55:12" added="2013-01-01 16:58:12" />
  <period something="2013-01-01 22:55:12" added="2013-01-01 22:58:12" />
  <period something="2013-01-02 04:55:12" added="2013-01-02 04:58:12" />
  <period something="2013-01-02 10:55:12" added="2013-01-02 10:58:12" />
  <period something="2013-01-02 16:55:12" added="2013-01-02 16:58:12" />
  <period something="2013-01-02 22:55:12" added="2013-01-02 22:58:12" />
</history>

…变成这样:

<?xml version="1.0" encoding="utf-8"?>
<history>
  <period something="2013-01-01 04:55:12" added="2013-01-01 04:58:12" />
  <period something="2013-01-01 10:55:12" added="2013-01-01 10:58:12" />
  <period something="2013-01-01 16:55:12" added="2013-01-01 16:58:12" />
  <period something="2013-01-01 22:55:12" added="2013-01-01 22:58:12" />
  <period something="2013-01-02 04:55:12" added="2013-01-02 04:58:12" />
  <period something="2013-01-02 10:55:12" added="2013-01-02 10:58:12" />
  <period something="2013-01-02 16:55:12" added="2013-01-02 16:58:12" />
</history>/>
    <period something="2013-01-02 22:55:12" added="2013-01-02 22:58:12" />
</history>

/>
因此,我删除的节点已返回,但文档的格式不再正确

为什么?? 有什么想法吗?

这就是问题所在:

new FileStream( fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite )
如果文件已存在,则将覆盖现有文件,但不会截断它

您应该指定
FileMode.Create
。。。或者更简单地说,只需使用获取流。更好的是,不必费心于
StreamWriter
StreamReaer
,甚至不用手动创建流。见鬼,加载文件时,只需指定文件名:

document = new XmlDocument();
document.Load(fileName);
为了保存,如果您确实需要自定义设置:

using (var writer = XmlWriter.Create(fileName, settings))
{
    document.Save(writer);
}    
我强烈建议您在编写文件时不要读取它,顺便说一句,在编写文件时,它无论如何都不是有效的XML文件


我还鼓励您尽可能从
XmlDocument
迁移到LINQ到XML(
XDocument
等),这是一个更好的API。

感谢Jon修复了它!我想迁移到LINQ,但我丢失了Xpath,我至少在这个应用程序中大量使用Xpath。@约翰:您仍然可以在LINQ to XML中使用Xpath-尽管我个人通常使用
元素
等结合
Where
子句来查询树。