Как сделать блокировку файлов Windows более похожей на блокировку файлов UNIX? - PullRequest
19 голосов
/ 13 февраля 2009

UNIX блокировка файлов очень проста: операционная система предполагает, что вы знаете, что вы делаете, и позволяет вам делать то, что вы хотите:

Например, если вы попытаетесь удалить файл, который другой процесс открыл, операционная система, как правило, позволит вам это сделать. Исходный процесс по-прежнему сохраняет свои файловые дескрипторы, пока не завершится - в этот момент файловая система тихо перезапустит дисковые ресурсы. Без суеты, вот как мне это нравится.

Как обстоят дела в Windows: если я пытаюсь удалить файл, который использует другой процесс, я получаю сообщение об ошибке операционной системы. Файл недоступен до тех пор, пока исходный процесс не снимет блокировку файла. Это было здорово в однопользовательские времена MS-DOS, когда любой процесс блокировки мог происходить на том же компьютере, на котором находились файлы, однако в сети это кошмар:

Рассмотрим, что происходит, когда процесс зависает во время записи в общий файл на файловом сервере Windows. Прежде чем файл может быть удален, мы должны найти компьютер и идентифицировать процесс на том компьютере, который первоначально открыл файл. Только тогда мы можем завершить процесс и удалить наш нежелательный файл.

Какая неприятность!

Есть ли способ сделать это лучше? Я хочу, чтобы блокировка файлов в Windows велась как блокировка файлов в UNIX. Я хочу, чтобы операционная система позволяла мне делать то, что я хочу, потому что я отвечаю и знаю, что я делаю ...

... так можно ли это сделать?

Ответы [ 4 ]

8 голосов
/ 13 февраля 2009

Нет. Windows предназначена для «среднего пользователя», то есть людей, которые ничего не понимают в компьютере. Поэтому ОС старается быть умной, чтобы избежать PEBKAC s. Цитирую Билла Гейтса: «В Windows нет проблем, которые хотят решить многие люди». Конечно, он знает, что 99,9999% всех пользователей Windows не могут сказать, сделала ли программа что-то странное из-за них или из-за парня, который это написал.

Unix был разработан, когда мир был более простым, и любой, кто был достаточно близко к компьютеру, чтобы прикоснуться к нему, вероятно, знал, как собрать его из грязного песка. Поэтому ОС обычно позволяет вам делать то, что вы хотите, потому что она предполагает, что вы знаете лучше (и если вы этого не сделали, вы будете в следующий раз).

Технический ответ: Unix выделяет «i-node», если вы создаете файл. I-узлы могут быть разделены между процессами. Если два процесса создают один и тот же файл (то есть два процесса вызывают create () с одинаковым путем), то в итоге вы получаете два i-узла. Это по замыслу. Это позволяет использовать необычную функцию безопасности: вы можете создавать файлы, которые никто не может открыть, кроме вас самих:

  1. Открыть файл
  2. Удалить его (но сохранить дескриптор файла)
  3. Используйте файл так, как вам нравится
  4. Закрыть файл

После шага № 2 единственный процесс в юниверсе, который может получить доступ к файлу, - это тот, кто его создал (если только вы не хотите читать жесткий диск блок за блоком). Операционная система будет поддерживать данные до тех пор, пока вы не закроете файл или пока ваш процесс не умрет (после этого Unix очистится после вас).

Этот дизайн является основой всех файловых систем Unix. Файловая система Windows NTFS работает почти так же, но API высокого уровня отличается. Многие приложения открывают файлы в эксклюзивном режиме (который не позволяет никому, даже программам резервного копирования) прочитать файл. Это справедливо даже для приложений, которые просто отображают информацию, например, средства просмотра PDF.

Это означает, что вам придется исправить все приложения Windows для достижения желаемого эффекта. Если у вас есть доступ к источнику, вы можете создать файл в режиме общего доступа. Это позволило бы другим процессам получить к нему доступ одновременно, но тогда вам придется перед каждым чтением / записью проверять, существует ли файл, внесены ли изменения и т. Д.

8 голосов
/ 13 февраля 2009

В соответствии с MSDN вы можете указать CreateFile () 3-й параметр (dwSharedMode) флаг общего режима FILE_SHARE_DELETE, который:

Включает последующие операции открытия файла или устройства для запроса доступа к удалению.

В противном случае другие процессы не могут открыть файл или устройство, если они запрашивают доступ для удаления.

Если этот флаг не указан, но файл или устройство были открыты для доступа для удаления, функция завершается ошибкой.

Примечание Доступ к удалению позволяет выполнять операции как удаления, так и переименования.

http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx

Так что, если вы можете контролировать свои приложения, вы можете использовать этот флаг.

3 голосов
/ 13 февраля 2009

Обратите внимание, что Process Explorer позволяет принудительно закрывать дескрипторы файлов (для процессов, локальных для блока, на котором вы его запускаете) через Handle -> Close Handle.

Unlocker призван сделать гораздо больше и предоставляет полезный список других инструментов.

Также возможно удаление при перезагрузке (хотя это звучит не так, как вы хотите)

1 голос
/ 13 февраля 2009

Это не очень помогает, если зависший процесс все еще держит ручку открытой. Он не освободит ресурсы, пока этот зависший процесс не освободит дескриптор. Но в любом случае в Windows можно принудительно закрыть файл из-под процесса, который его использует. Process Explorer от sysinternals.com позволит вам посмотреть и закрыть дескрипторы, которые открыты процессом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...