Question

Je Hava un programme Java qui doit surveiller une arborescence de répertoires pour les changements. J'ai le code JNI qui utilise ReadDirectoryChangesW(). Le répertoire est ouvert comme:

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

et puis je passe à dirHandle ReadDirectoryChangesW(). Tout cela fonctionne très bien.

Le problème est que d'autres parties du code (du côté Java) utilisent File.setLastModified() aux fichiers « tactiles » ou des répertoires (mettre à jour leurs estampilles pour être « maintenant »). Cela fonctionne en général; cependant, il échoue lorsqu'il a essayé de « toucher » le répertoire qui a été ouvert à l'aide CreateFile().

Pour voir quelle erreur de Windows se produit réellement, je regardais à la source JDK pour File.setLastModified() et Réimplémentée dans mon propre code avec l'ajout d'impression de l'erreur GetLastError(); l'erreur est:

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

WTF? Il est le même processus. J'ai même passé FILE_SHARE_READ et FILE_SHARE_WRITE à CreateFile().

Y at-il un moyen de faire ce travail?

Plus d'infos

Le code natif de la mise en œuvre File.setLastModified() dans le JDK fait un:

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

Si je change le premier 0 à FILE_SHARE_READ | FILE_SHARE_WRITE, tout cela fonctionne. Il semble donc que la mise en œuvre est un peu JDK cassé. : (

Alors, ma question devient maintenant: Est-il possible de faire ce travail sans avoir à utiliser mon propre (re) mise en œuvre de File.setLastModified()

Était-ce utile?

La solution

Bien que le message d'erreur est un peu trompeur dans ce cas, ce que vous voyez est un comportement normal.

En ouvrant le répertoire avec jeu de dwShareMode à zéro, le JDK est, en effet, en demandant pour un accès exclusif, ce qui entraînera toute autre tentative d'accès à l'échec avec une erreur de violation de partage. Cela vaut également pour les accès d'autres processus et à partir de votre propre processus.

La documentation CreateFile décrit le paramètre dwShareMode:

  

Si ce paramètre est égal à zéro et CreateFile réussit, le fichier ou le périphérique ne peuvent être partagés et ne peut être ouvert à nouveau jusqu'à ce que la poignée au. Fichier ou le périphérique est fermé

     

Vous ne pouvez pas demander un mode de partage qui est en conflit avec le mode d'accès qui est spécifié dans une demande existante qui a une poignée ouverte. CreateFile échouerait et la fonction GetLastError retournerait ERROR_SHARING_VIOLATION.

Alors, il semble que vous avez répondu à votre question. Vous avez besoin d'une fonction setLastModified personnalisée qui spécifie FILE_SHARE_READ | FILE_SHARE_WRITE lors de l'accès au répertoire

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top