Файл может быть «заблокирован» по двум причинам:
- Фактического файл lock , который предотвращает запись и, возможно, чтение из файла.
- Файл открыт без доступа (случайно или добровольно) , который даже препятствует открытию ручки. Если вы уже видите ошибку
CreateFile
, это скорее всего случай, а не реальный замок.
Есть концептуально [1] по крайней мере, два пути, зная, что никакой другой процесс не заблокировал файл без напряженного ожидания:
- Находя, кто держит замки и ждет от процесса или нить для выхода (или, по наповал убивает их ...)
- блокируя файл сами
Кто держит замки?
Выяснить о владельцах замка довольно противный, вы можете сделать это через полностью незарегистрированнойSystemLocksInformation
класса, используемый с недокументированными NtQuerySystemInformation
функции (последний «только без документов», но бывший так много документирован, что это очень трудно чтобы найти любую информацию вообще). Возвращенная структура объясняется here и содержит идентификатор принадлежащего потока.
К счастью,, удерживая замок, предполагает наличие ручки. Закрытие дескриптора файла разблокирует все диапазоны файлов. Это означает: без блокировки без ручки.
Иными словами, проблема также может быть выражена как «кто держит открытую ручку в файле?». Конечно, не все процессы, которые содержат дескриптор файла, будут заблокированы, но никакой процесс с дескриптором гарантирует, что процесс не заблокирован.
Код для определения того, какие процессы имеют открытый файл, намного проще (с использованием диспетчера перезапуска) и readily available на сайте Raymond Chen.
Теперь, когда вы знаете, какие процессы и потоки хранят файлы и блокировки файлов, создайте список всех ручек потока/процесса и используйте WaitForMultipleObjects
в списке обработчиков процессов. Когда процесс завершается, все дескрипторы закрыты.
Это также прозрачно рассматривает возможность «блокировки», потому что процесс не передает доступ.
Блокировка файла самостоятельно
Вы можете использовать LockFileEx
, который работает асинхронно. Обратите внимание: LockFileEx
нужен действительный дескриптор, который был открыт с либо права на чтение или запись (получение разрешения на запись может быть невозможным, но чтение должно работать почти всегда - даже если вам запрещено фактически с чтением с помощью эксклюзивной блокировки , все равно можно создать дескриптор, который мог бы читать, если бы не было блокировки).
Вы можете подождать при асинхронной блокировке, чтобы завершить либо через событие в структуре OVERLAPPED
, либо на порте завершения, но и даже сделать другие полезные вещи в среднее время. Как только вы заблокировали файл, вы знаете, что никто его не заблокировал.
[1] формулировка
«концептуально» предполагает, что я уверен, что любой метод будет работать, но я не проверял их.
Жесткие диски не имеют проблем с «всегда работает», это то, что они предназначены для ... –
@JonathanPotter Я не согласен. Если жесткий диск остается в одном секторе, будут задержки и отставание в производительности. Также он изнашивается. Если такие вещи обрабатываются в памяти, это совсем другая история. –
Мой комментарий был немного увлекательным, я дам вам. Но вам не нужно беспокоиться. Файловая система кэшируется в памяти. Неоднократно попытка открыть дескриптор файла почти наверняка не коснется диска. –