Как заблокировать доступ к файлу, когда его открыл пользователь? - PullRequest
2 голосов
/ 20 февраля 2010

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

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

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

Ответы [ 3 ]

5 голосов
/ 20 февраля 2010

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

2 голосов
/ 20 февраля 2010

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

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

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

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

2 голосов
/ 20 февраля 2010

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

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

...