Удалить файл, открытый для монопольного доступа в том же процессе - PullRequest
8 голосов
/ 01 августа 2011

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

Я использую функцию CreateFile () для открытия таких файлов. Чтобы гарантировать, что другая программа закончила запись в файл и закрыла его, я установил для параметра dwShareMode значение 0. Если CreateFile завершился неудачно с ошибкой общего доступа, я просто пропускаю файл до следующего изменения.

Проблема в том, что DeleteFile () завершается с ошибкой ERROR_SHARING_VIOLATION, когда файл открывается моей программой.

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

Я использую этот код для открытия файлов

CreateFile(filePath,DELETE|FILE_READ_DATA,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)

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

Ответы [ 2 ]

6 голосов
/ 01 августа 2011

FILE_FLAG_DELETE_ON_CLOSE - это, вероятно, то, что вы ищете.От MSDN

* FILE_FLAG_DELETE_ON_CLOSE 0x04000000 - файл должен быть удален сразу после закрытия всех его дескрипторов, который включает указанный дескриптор и любые другие открытые или дублированные дескрипторы.Если в файле существуют открытые дескрипторы, вызов не будет выполнен, если они не были открыты в режиме общего доступа FILE_SHARE_DELETE.Последующие запросы на открытие файла не будут выполнены, если не указан режим общего доступа FILE_SHARE_DELETE. *

РЕДАКТИРОВАТЬ: добавлен пример ...

Итак, в вашем случае вы должны:

HANDLE hFile = ::CreateFile(filePath,
                DELETE|FILE_READ_DATA,
                0,
                NULL,
                OPEN_EXISTING,
                FILE_FLAG_DELETE_ON_CLOSE,
                NULL);

//use the file...

::CloseHandle(hFile); //the file gets deleted when the handle is closed
4 голосов
/ 01 августа 2011

Передать FILE_SHARE_DELETE для dwShareMode. Обратите внимание, что это все еще позволит другим приложениям (а также вашим собственным) вызывать DeleteFile () во время чтения файла, но согласно документации DeleteFile () он не будет удален, пока вы вызовите CloseHandle (), чтобы закрыть дескриптор чтения.

Функция DeleteFile помечает файл для удаления при закрытии. Следовательно, удаление файла не происходит, пока последний дескриптор файла закрыто. Последующие вызовы CreateFile для открытия файла завершаются неудачно с ERROR_ACCESS_DENIED.

Другие приложения не смогут читать или записывать файл, если вы не укажете FILE_SHARE_READ или FILE_SHARE_WRITE соответственно. Хотя с FILE_SHARE_DELETE можно переместить файл, но это было бы так.

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