Как да заключа достъпа до файл, когато потребител го е отворил?

Пиша 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 и FileStream.Unlock методи

person Mitch Wheat    schedule 20.02.2010

Ако използвате метода File.Open за отваряне на файловия поток към вашите файлове, уверете се, че използвате претоварването, което отнема FileShare параметър (този). Можете да зададете това на различни стойности, за да укажете как потокът трябва да заключва файла, докато се използва (т.е. да разреши четене от други процеси, но не и запис, да предотврати всякакво използване от други процеси). Нуждаете се от стойността None, за да предотвратите достъпа на всеки друг процес (или друг поток във вашия процес) до файла.

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

person adrianbanks    schedule 20.02.2010