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

War es hilfreich?

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 die GetLastError Funktion würde ERROR_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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top