Каков наилучший способ заблокировать файл, чтобы предотвратить доступ к нему нескольких пользователей
У меня есть приложение Windows Form, в котором пользователи могут открывать, создавать и сохранять 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();
Я хотел бы отобразить сообщение о том, какое имя пользователя / компьютера имеет открытый файл, если другой пользователь пытается открыть его или перезаписать с помощью сохранения как. Я рассматриваю возможность создания файла блокировки при его открытии. Есть ли лучший способ справиться с этим?
4 ответа
Файл блокировки будет единственным способом, если вы хотите отобразить дополнительную информацию.
Если вы хотите запретить пользователям открывать файл, когда он был открыт другим пользователем, вам понадобится FileShare.None
ENUM.
Вы должны заменить
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
пока файл не будет закрыт.
Вы можете справиться с этим, только заблокировав доступ для записи, тем самым позволив другим по-прежнему читать файл:
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();
}
Это фрагмент из функции синхронизированного регистратора. Он недоступен до тех пор, пока запись не завершится и не станет потокобезопасным.
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();
}
}
}
}