У меня есть 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."
WTF? Это тот же процесс. Я даже передал 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()
?