Как заблокировать доступ к файлу, когда он открыт пользователем?

Я пишу программу C # .NET, которая использует XmlSerializer для сериализации и десериализации проекта, над которым работает текущий пользователь, в XML-файл и обратно. Это работает нормально, но я пытаюсь найти способ запретить двум пользователям открывать один и тот же файл с сетевого диска и заставлять одного пользователя перезаписывать сохранение предыдущего пользователя. По сути, мне нужно поведение, которое имеет MS Word, когда, если программа не может получить доступ на запись к файлу при его открытии, она открывает файл в режиме только для чтения.

Итак, как мне заблокировать доступ к файлу? Могу ли я просто оставить объект файлового потока открытым и сохранить на него ссылку? Могу ли я продолжать использовать один и тот же объект файлового потока для любых промежуточных сохранений, а не открывать и закрывать их для каждого сохранения? Или есть другой способ заблокировать доступ к файлу?

Также как я могу гарантировать, что файл будет выпущен, даже если мое приложение выйдет из строя? Будет ли это хорошим случаем для реализации IDisposable?


person Eric Anastas    schedule 20.02.2010    source источник


Ответы (3)


Вам не нужно делать ничего особенного, чтобы это работало. Сначала попробуйте открыть файл с помощью FileAccess.ReadWrite и FileShare.Read. Если вы не получите IOException, у вас будет эксклюзивный доступ на запись к файлу. Другие процессы могут читать из файла, но никогда не могут получить доступ для записи.

Если эта попытка открытия не удалась, вы можете предположить, что кто-то уже открыл файл для записи. Теперь переключите внутреннюю логику программы в режим «только для чтения» и откройте файл с помощью FileAccess.Read и FileShare.ReadWrite. Если это все еще бомба, значит, с файлом что-то в корне не так, IOException сообщает вам, что.

Будьте очень осторожны, чтобы избежать проверки «заблокирован ли файл». Это не может работать надежно в сети, вы должны держать файл открытым после получения к нему доступа. Как только вы закроете его, другой процесс сможет получить к нему доступ через наносекунду.

Еще одна типичная проблема с такого рода блокировкой заключается в том, что пользователь обычно хочет знать, кто заблокировал файл. Windows не предоставляет стандартного способа узнать. Office решает эту проблему, создавая скрытый файл в том же каталоге с тем же именем, что и файл, но с другим расширением имени файла. Он записывает имя пользователя в этот файл, доступное любому процессу, который обнаруживает, что файл заблокирован. Вы можете сделать то же самое, Environment.UserName подойдет для этого.

person Hans Passant    schedule 20.02.2010
comment
Хорош ли такой подход, когда дело касается нескольких файлов? Будет ли это ухудшать производительность системы при использовании большого количества файлов? - person techno; 22.11.2013

Вы можете использовать FileStream.Lock и _ 2_ методы

person Mitch Wheat    schedule 20.02.2010

Если вы используете метод File.Open для открытия файлового потока в свои файлы, убедитесь, что вы используете перегрузку, которая принимает _ 2_ параметр (этот один). Вы можете установить для него различные значения, чтобы указать, как поток должен блокировать файл во время использования (т. Е. Разрешить чтение другим процессам, но не запись, предотвратить любое использование другими процессами). Вам нужно значение None, чтобы предотвратить доступ к файлу любого другого процесса (или другого потока в вашем процессе).

Чтобы файл был освобожден, не забудьте закрыть FileStream, когда закончите с ним. Чтобы обеспечить его закрытие, даже если ваше приложение выйдет из строя, вам не нужно делать ничего особенного - если ваше приложение выйдет из строя, его процесс завершится, и блокировка будет снята.

person adrianbanks    schedule 20.02.2010