我在C#中有一个使用XML配置文件的WinForms应用程序。
为了防止其他应用和用户在应用运行时编辑这些文件,我使用了...
打开文档:
document = new XmlDocument();
using ( var xr = new StreamReader( new FileStream( fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read ), Encoding.UTF8 ) )
{
document.Load( xr );
}
...一个Save()方法,它使用writer再次保存文件。
lock ( syncLock )
{
using ( var writer = XmlTextWriter.Create( new FileStream( fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read ), settings ) )
{
document.Save( writer );
}
}
由于多个线程可能希望保存到文件,因此存在锁定。我实际上不确定这是否有任何意义。
当我为了isntance,从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>
因此我删除的节点又回来了,但文档不再格式良好。
为什么呢? 有什么想法吗?
答案 0 :(得分:1)
这是问题所在:
new FileStream( fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite )
如果该文件已存在,则会覆盖现有文件,但不会截断它。
您应该指定FileMode.Create
...或更简单,只需使用File.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。