锁定文件以防止多个用户访问它的最佳方法是什么



我有一个Windows表单应用程序,用户可以在其中打开,创建和保存xml文件。文件通常保存到网络文件夹。我需要确保给定的文件一次只能由一个用户打开。xml 文件将加载到树控件中,并在会话期间频繁保存。(几乎任何时候单击树节点时)我像这样打开文件:

FileStream fs = new FileStream(m_Filename, FileMode.Open);
XmlReader reader = new XmlTextReader(fs);
XmlSerializer deserializer = new XmlSerializer(typeof(BaseBoardTest));
m_TestNodes = (BaseBoardTest)deserializer.Deserialize(reader);
fs.Close();

像这样保存:

TextWriter writer = new StreamWriter(filename);
XmlSerializer serializer = new XmlSerializer(typeof(BaseBoardTest));
serializer.Serialize(writer, m_TestNodes);
writer.Close();

我想显示一条消息,说明如果其他用户尝试打开文件或通过另存为覆盖文件,则哪个用户/计算机名称打开了该文件。我正在考虑在打开文件时创建一个锁定文件。有没有更好的方法来解决这个问题?

如果要显示其他信息,锁定文件将是唯一的方法。

如果要阻止用户在其他用户打开文件时打开文件,则需要FileShare.None枚举。

您应该替换

new FileStream(m_Filename, FileMode.Open);

new FileStream(m_Filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None)

有关 FileShare.None 的更多信息,请参见:http://msdn.microsoft.com/en-us/library/system.io.fileshare.aspx

注意:请务必捕获尝试打开文件时引发的任何异常。 如果一个用户打开了该文件,则任何打开该文件的后续请求都将引发System.IO.IOException,直到文件关闭为止。

这是来自同步记录器功能的代码片段。在写入完成并且是线程安全的之前,它无法访问。

internal class WriteToLockedFile
    {
        internal static string Uri { get; set ; }
        private static readonly object _syncObject = new object();
        public static void WriteToFile(string logMessage)
        {
            using (var stream = TextWriter.Synchronized( File.AppendText(Uri)))
            {
                lock (_syncObject) 
                {
                    stream.WriteLine(" {0}", logMessage); stream.Flush(); 
                }
            }
        }
    }

您可以通过仅锁定写入访问权限来处理此问题,从而允许其他人仍读取文件:

using (FileStream fs = new FileStream(m_Filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
{
   XmlReader reader = new XmlTextReader(fs);
   XmlSerializer deserializer = new XmlSerializer(typeof(BaseBoardTest));
   m_TestNodes = (BaseBoardTest)deserializer.Deserialize(reader);
   fs.Close();
   TextWriter writer = new StreamWriter(filename);
   XmlSerializer serializer = new XmlSerializer(typeof(BaseBoardTest));
   serializer.Serialize(writer, m_TestNodes);
   writer.Close();
}

相关内容

  • 没有找到相关文章

最新更新