Установка времени последнего изменения каталога, открытого для ReadDirectoryChangesW

StackOverflow https://stackoverflow.com/questions/1144635

Вопрос

У меня есть Java-программа, которой необходимо отслеживать дерево каталогов на предмет изменений.У меня есть код JNI, который использует ReadDirectoryChangesW().Каталог открывается следующим образом:

HANDLE dirHandle = CreateFile(
    path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL
);

и тогда я прохожу мимо dirHandle Для ReadDirectoryChangesW().Все это работает просто отлично.

Проблема в том, что другие части кода (на стороне Java) используют File.setLastModified() чтобы "прикоснуться" к файлам или каталогам (обновите их временные метки, чтобы они были "сейчас").Обычно это работает;однако при попытке "коснуться" каталога, который был открыт с помощью CreateFile().

Чтобы узнать, какая ошибка Windows на самом деле возникает, я просмотрел исходный код JDK для File.setLastModified() и переопределил это в моем собственном коде с добавлением вывода ошибки из GetLastError();ошибка заключается в:

ERROR_SHARING_VIOLATION (error 32)
"The process cannot access the file because it is being used by another process."

ВТФ?Это тот самый то же самое процесс.Я даже прошел мимо FILE_SHARE_READ и FILE_SHARE_WRITE Для CreateFile().

Есть ли способ заставить это работать?

Подробная информация

Реализация в машинном коде File.setLastModified() в JDK выполняется:

h = CreateFileW(pathbuf, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);

Если я изменю первый 0 Для FILE_SHARE_READ | FILE_SHARE_WRITE, все это работает.Таким образом, кажется, что реализация JDK немного нарушена.:(

Итак, теперь мой вопрос становится:Есть ли способ заставить это работать без необходимости использовать мою собственную (повторную) реализацию File.setLastModified()?

Это было полезно?

Решение

Хотя сообщение об ошибке в данном случае немного вводит в заблуждение, то, что вы видите, является нормальным поведением.

Открыв каталог с помощью dwShareMode при равном нулю JDK, по сути, запрашивает эксклюзивный доступ, что приведет к сбою любой другой попытки доступа с ошибкой нарушения общего доступа.Это в равной степени относится к доступам как из других процессов, так и из вашего собственного процесса.

Тот Самый CreateFile Документация описывает dwShareMode параметр:

Если этот параметр равен нулю и CreateFile выполняется успешно, файл или устройство не могут быть доступны для общего доступа и не могут быть открыты снова до тех пор, пока не будет закрыт дескриптор файла или устройства.

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

Итак, похоже, вы сами ответили на свой вопрос:вам нужен индивидуальный подход setLastModified функция, которая определяет FILE_SHARE_READ | FILE_SHARE_WRITE при обращении к каталогу.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top