Einstellen der letzten Änderung Zeit eines Verzeichnisses für ReadDirectoryChangesW geöffnet
-
16-09-2019 - |
Frage
ich ein Java-Programm hava, das einen Verzeichnisbaum für Änderungen überwachen muss. Ich habe JNI-Code, der ReadDirectoryChangesW()
verwendet. Das Verzeichnis wird geöffnet wie:
HANDLE dirHandle = CreateFile(
path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL
);
und dann gehe ich dirHandle
ReadDirectoryChangesW()
. Das alles funktioniert gut.
Das Problem ist, dass andere Teile des Codes (auf der Java-Seite) File.setLastModified()
verwenden, um „touch“ Dateien oder Verzeichnisse (ihre Zeitstempel aktualisieren „jetzt“ zu sein). Dies funktioniert im Allgemeinen; jedoch scheitert es, wenn es versucht, das Verzeichnis zu „berühren“, die geöffnet wurde CreateFile()
verwendet wird.
Um zu sehen, was Windows-Fehler tatsächlich auftreten, habe ich an der JDK Quelle für File.setLastModified()
gesucht und neu implementiert es in meinem eigenen Code mit dem Zusatz von Drucken den Fehler von GetLastError()
; der Fehler ist:
ERROR_SHARING_VIOLATION (error 32)
"The process cannot access the file because it is being used by another process."
WTF? Es ist der gleiche Prozess. Ich selbst FILE_SHARE_READ
und FILE_SHARE_WRITE
zu CreateFile()
übergeben.
Gibt es eine Möglichkeit, diese Arbeit zu machen?
Weitere Informationen
Die native Code-Implementierung von File.setLastModified()
im JDK funktioniert ein:
h = CreateFileW(pathbuf, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
Wenn ich den ersten 0
ändern FILE_SHARE_READ | FILE_SHARE_WRITE
, alles funktioniert. So scheint es, dass die JDK-Implementierung ein wenig gebrochen ist. : (
Also meine Frage jetzt wird: Gibt es eine Möglichkeit, diese Arbeit zu machen, ohne dass meine eigene (Wieder-) Einführung von File.setLastModified()
verwenden
Lösung
Obwohl die Fehlermeldung ist ein bisschen in diesem Fall irreführend, was Sie sehen, ein normales Verhalten ist.
Durch das Verzeichnis mit dwShareMode
auf Null gesetzt Öffnen wird das JDK in der Tat fragen, für die exklusiven Zugriff, die anderen Zugriffsversuch verursacht eine Zugriffsverletzung Fehler zum Scheitern verurteilt. Dies gilt gleichermaßen für Zugriffe
aus anderen Prozessen und aus Ihrem eigenen Prozess.
Die CreateFile
Dokumentation dwShareMode
Parameter beschreibt:
Wenn dieser Parameter Null ist und Create erfolgreich ist, die Datei oder das Gerät kann nicht mit anderen geteilt werden und kann nicht wieder bis zum Griff in die Datei oder das Gerät geöffnet werden geschlossen.
Sie können einen Verteilungsmodus anfordern, die mit dem Zugriffsmodus Konflikte, die in einer bestehenden Anforderung spezifiziert ist, der einen offenen Griff hat.
CreateFile
würde fehlschlagen und dieGetLastError
Funktion würdeERROR_SHARING_VIOLATION
zurück.
Also, es scheint, dass Sie Ihre eigene Frage beantwortet haben. Sie eine benutzerdefinierte setLastModified
Funktion benötigen, die FILE_SHARE_READ | FILE_SHARE_WRITE
gibt an, wann das Verzeichnis zugreifen