Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.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# 程序生成的xml文件上的共享冲突_C#_Xml - Fatal编程技术网

C# 程序生成的xml文件上的共享冲突

C# 程序生成的xml文件上的共享冲突,c#,xml,C#,Xml,我正在使用monodevelop编写一个C#console应用程序,最近我决定使用xml文件作为存储用户偏好的方式。创建、写入初始数据和读取文件都很容易完成,从我所看到的情况来看,更新文件也应该很容易。但是,下面的代码在路径上生成共享冲突: public void Update (string username, PreferenceAttribute preferencename, string newvalue) { try {

我正在使用monodevelop编写一个C#console应用程序,最近我决定使用xml文件作为存储用户偏好的方式。创建、写入初始数据和读取文件都很容易完成,从我所看到的情况来看,更新文件也应该很容易。但是,下面的代码在路径上生成共享冲突:

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);