9
votes

Alternative au fichier.exists () en Java

Je n'ai jamais pensé que cela m'arriverait, mais j'ai couru dans mon premier bogue en Java:

http://bugs.sun.com/bugdatabase/view_bug.do ? bug_id = 5003595

Je suis à peu près dans la même situation exacte que celle décrite dans le bogue (NFS sur Linux), et je vois que fichier.exists () ne renvoie pas la valeur correcte (à moins pas tout de suite).

Donc, ma question est, existe-t-il une alternative à cette méthode de vérification si un fichier existe? Je préférerais que cela soit agnostique du système d'exploitation si possible.

Edit: J'ai trouvé une solution de contournement. Si vous appelez un appel à LS $ Filedir , le NFS rafraîchit le cache / métadonna qui donne des problèmes Java, et fichier.exists () renvoie la valeur correcte. Certes, ce n'est pas totalement idéal, car cela blesse la portabilité, mais il existe des moyens de faire face à ce problème.


4 commentaires

Quel genre de fichier est-ce? Vous recherchez un type particulier de fichier? Ou n'importe quel fichier? Vous pouvez exécuter System.Exec ("LS") et analyser les résultats pour votre fichier. Bien que je suis sûr qu'il y ait des moyens plus facilement, je vais donc laisser ceci comme un mègre


Ce bug est spécifique à Java 1.4.2_03, qui a atteint la fin de son cycle de vie de soutien il y a des années. Par curiosité, pourquoi ne pas simplement migrer vers Java 5 ou UP? Avez-vous essayé de tester avec un JRE soutenu pour voir quelque chose de pauses?


@Steve: Je suis en train d'exécuter Java 6. Je suppose que depuis qu'ils marquaient "ne corrigeront pas" pour ce bogue, qu'il n'est pas réparé dans une version de Java. Au moins, c'est ce que le comportement de mon application me dit.


Bizarre. Je suis d'accord avec Ben ci-dessous, dans ce fichier.exists () peut signaler de faux positifs (c'est-à-dire dire qu'un fichier existe quand ce n'est pas). Cependant, un faux négatif est différent (c'est-à-dire dire qu'un fichier n'existe pas quand il est assis là). Ce rapport de bogue a plus de 6 ans et les commentaires indiquent qu'ils s'attaquaient à cela dans le développement de JSR 203 ... Donc, si vous le voyez toujours dans un JRE contemporain, je déposerais un nouveau rapport de bogue. Cependant, les deux réponses ci-dessous sont très correctes ... La meilleure solution de contournement est simplement des blocs d'essais.


6 Réponses :


5
votes

Tous fichier.exists vous indique que le fichier existait à un moment donné dans le passé. Cela ne vous dit pas:

  • si cela existera lorsque vous essayez de l'ouvrir
  • si vous avez la permission de l'ouvrir
  • Quelque chose d'utile du tout, vraiment

    Essayez donc de concevoir votre application afin qu'il puisse gérer des fichiers qui n'existent pas sans essayer de vérifier cela à l'avance. (Vous devrez gérer diverses exceptions lorsque vous travaillez avec le fichier.)


1 commentaires

Vous supposez que je vais ouvrir le fichier plus tard, ce qui n'est pas vrai dans ma situation particulière. Je ne finis pas réellement à ouvrir le fichier dans ma demande du tout; Je vérifie l'existence pour d'autres raisons.



6
votes

Que se passe-t-il si fichier.exists () renvoie true, alors une personne supprime le fichier / votre montage NFS disparaît, puis vous essayez d'ouvrir le fichier? Fondamentalement, fichier.exists () est inutile car vous devez gérer les exceptions pouvant survenir à partir de l'ouverture du fichier de toute façon.


0 commentaires

2
votes

L'alternative évidente est fichier.File () . Essayez cela en premier.

Bien qu'il devienne inexact lors de la lecture de fichiers en lecture seule, vous pouvez toujours utiliser le fichier fichier.canwrite () pour vérifier si le fichier existe.

Si les deux ci-dessus échouent, vous pouvez utiliser le fichier Longueur () . Si elle renvoie 0L , vous savez que le fichier n'existe pas.


0 commentaires

3
votes

Je remarque que java.nio.file.path.exists () méthode renvoie false si le fichier n'existe pas ou son existence peut 't être déterminé . Il semblerait donc que les faux négatifs seront déployés pendant un moment et que votre code devra les tolérer.


0 commentaires

7
votes

Le problème de base que vous avez avec NFS est qu'il cache des attributs, des fichiers et des annuaires. Cela signifie que les informations peuvent être obsolètes. Vous pourrez peut-être désactiver la mise en cache, vous verrez une réduction significative des performances.

La chose importante à retenir est que NFS n'est pas un service de messagerie et n'est pas conçu pour la livraison rapide des données.


1 commentaires

Ceci est à peu près aussi proche d'une réponse que je peux marquer. Le problème réside vraiment plus étroitement au fait qu'un NFS est utilisé. Dans ma situation, un fichier avec nom de fichier x.file est effectué, puis supprimé, puis ré-réalisé avec le même nom (x.file). Une fois que cela est ré-établi, les appels à Stat sur le dossier affirment que cela n'existe pas. L'appelant «LS» sur l'ensemble du répertoire semble rafraîchir le cache et réparer le problème du fichier de java.exists () et des appels vers Stat commencent également à revenir correctement. Cela semble indiquer que le problème est davantage à voir avec NFS que Java.



7
votes

J'ai rencontré le même problème et j'ai résolu l'appel avec un appel à fichier.geparentfile (). Liste () . Essentiellement la même chose que votre solution, mais le système d'agnostique.


1 commentaires

@StevecoCohen Il fait probablement basculer que ce que le cache soit examiné. Auquel cas cela implique également une pénalité de performance.