C# 程序生成的xml文件上的共享冲突
我正在使用monodevelop编写一个C#console应用程序,最近我决定使用xml文件作为存储用户偏好的方式。创建、写入初始数据和读取文件都很容易完成,从我所看到的情况来看,更新文件也应该很容易。但是,下面的代码在路径上生成共享冲突:C# 程序生成的xml文件上的共享冲突,c#,xml,C#,Xml,我正在使用monodevelop编写一个C#console应用程序,最近我决定使用xml文件作为存储用户偏好的方式。创建、写入初始数据和读取文件都很容易完成,从我所看到的情况来看,更新文件也应该很容易。但是,下面的代码在路径上生成共享冲突: public void Update (string username, PreferenceAttribute preferencename, string newvalue) { try {
public void Update (string username, PreferenceAttribute preferencename, string newvalue)
{
try
{
...
//this is where it throws exception \/
using (FileStream fs = new FileStream (filepath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
string attribute = preferencename.ToString ();
doc = new XmlDocument ();
doc.Load (fs);
fs.Close ();
XmlNode user = doc.SelectSingleNode ("//Users/User[@Name = '" + username + "']");
XmlNode pref = user.SelectSingleNode("Pref");
pref.Attributes[attribute].Value = newvalue;
doc.Save (fs);
}
} catch (Exception ex)
{
//error details output
}
}
省略using块会导致在doc.save(fs)行发生错误,并导致文件丢失其拥有的所有数据。我看过其他帖子,但唯一的解决方案似乎是使用块。我需要一种获得文件锁的方法(除非我的代码产生了问题)。有什么帮助吗
编辑:以下是我试图编辑的xml文档:
<?xml version="1.0" encoding="utf-8"?>
<!--Do not modify this auto-generated file. Doing so will cause unwanted behavior. If modification causes problems, delete this file and rerun the program-->
<Users>
<User Name="Ben" Password="hello54">
<Pref Gender="Male" Admin="false" Butler="Alfred" Eastereggs="false" />
</User>
<User Name="Admin" Password="admin">
<Pref Gender="Male" Admin="true" Butler="Butler" Eastereggs="false" />
</User>
</Users>
您的代码有两个问题 如果请求对文件进行写访问(
FileAccess.ReadWrite
),则不能允许其他流/线程/程序同时读取(FileShare.read
)
问题是,一旦关闭流
(例如文件流
,您就无法再对其进行读/写)。您给操作系统一个信号,表示该文件现在可以被其他程序使用
该问题的一个潜在解决方案是使用该文件两次:
using (FileStream fs = new FileStream (filepath, FileMode.Open, FileAccess.Read, FileShare.Read)) {
string attribute = preferencename.ToString ();
doc = new XmlDocument ();
doc.Load (fs);
}
XmlNode user = doc.SelectSingleNode ("//Users/User[@Name = '" + username + "']");
XmlNode pref = user.SelectSingleNode("Pref");
pref.Attributes[attribute].Value = newvalue;
using (FileStream fs = new FileStream (filepath, FileMode.Open, FileAccess.Write, FileShare.None)) {
doc.Save (fs);
}
您可以通过以下方式替换第二部分:
doc.Save (filepath);
为什么你要在使用它的时候关闭流?当我第一次开始研究这个问题时,一个引导我到使用块的解决方案推荐了这个(我想是因为XMLDATA接管了流并创建了它自己的?)。我不完全确定这是否是问题所在,因为堆栈跟踪显示using语句行中发生的错误。@BenKnoble:您能提供堆栈跟踪吗?它可能会在using
块中显示错误,因为在该块结束时,流将再次关闭
d。@CommuSoft在这里:@BenKnoble:可能会用stacktrace更新问题。。。我不认为注释用于此。这有一些帮助:我通过了第一个using块,但尝试加载第二个using块失败。如果用doc.Save(filepath)
替换第二个using
部分会怎么样?代码爆炸:P它导致了相同的共享冲突,但没有被try块捕获,因此xml数据消失了,下一次读取导致了一个意外错误,因为没有dataHmm。那么我想你的程序还在某处打开文件。在Linux中,您可以使用进程id运行lsof-p pid
,以列出进程打开的文件。也许你可以检查文件是否打开。我喜欢linux(用来运行Ubuntu),但现在在Macbook上。我尝试了几种方法来查看文件是否被某个进程使用或在某处打开,但运气不太好。lsof在Mac上有效吗?如果有效,最好的使用方法是什么?
doc.Save (filepath);