web-dev-qa-db-fra.com

Pourquoi 'File.exists' renvoie-t-il true, alors que 'Files.exists' dans la classe NIO 'Files' renvoie false

J'essaie de déterminer si un fichier existe dans un dossier réseau:

// File name is "\\QWERTY\folder\dir\A123456.TXT"
Path path = Paths.get("\\\\QWERTY\\folder\\dir\\A123456.TXT")

Utilisation de NIO Files:

Files.exists(path) == false

Utilisation de File:

path.toFile().exists() == true

Utiliser File semble être le bon selon nos tests. Pourquoi File fonctionne-t-il mieux que Files?

Alors, c'est quoi? Ne peut pas être les deux!

Mais attendez, il y a aussi Files.notExists(path).

Lorsque le fichier de partage réseau existe réellement

Files.exists(path): false
Files.notExists(path): false
path.toFile().exists(): true

Quand le fichier de partage réseau fait réellement pas existe

Files.exists(path): false
Files.notExists(path): true
path.toFile().exists(): false

Une autre façon tout aussi folle de regarder les trois résultats ci-dessus

boolean exists = Files.exists(path) || !Files.notExists(path)
boolean notExists = Files.notExists(path) || !Files.exists(path)
boolean oldFashionedExists = path.toFile().exists()

:Smiley:

Environnement et commentaires

Le programme s'exécute sur une machine Windows 8.1 Pro 32 bits (système d'exploitation et machine) et vérifie un partage réseau à partir d'une machine Windows 2008 R2 (32 bits).

Pour déterminer que Files.exists a échoué, j'ai installé WatchService pour surveiller le dossier et constaté que le fichier existait déjà lors de la vérification de Files.exists. J'ai ensuite connecté en tant que les deux méthodes et trouvé File.exists comme étant la bonne.

Maintenant, dans mon code, j'ai le chèque en tant que Files.exists(path) || path.toFile().exists().

Kinda semble stupide de devoir faire les deux. Probablement pourrait juste sortir avec le plus tard. J'essaie juste de laisser le doute aux ingénieurs d’Oracle, mais c’est ridicule de dire qu’ils signalent des choses différentes.

De plus, je me moque de savoir si "existe" est immédiatement obsolète. Je veux juste savoir si le fichier existe au moment où nous vérifions. Je n'ai jamais vu cela - nous venons de passer 30 heures entre moi et un autre développeur pour essayer de comprendre pourquoi nos programmes ne s'interfacent pas à cause de cette "fonctionnalité".

Médite sur ce moment

File.exists (): Renvoie true si et seulement si le fichier ou le répertoire désigné par ce chemin abstrait existe ; faux sinon.

Files.exists (): renvoie true si le fichier existe; false si le fichier n'existe pas ou si son existence ne peut pas être déterminée.

Cela me fait craquer! "si et seulement si le fichier ou le répertoire désigné par ce chemin abstrait existe; false sinon" est en désaccord avec "true si le fichier existe; false si le fichier n'existe pas ou si son existence ne peut pas être déterminée" 

Alors, comment encore File.exists peut-il être vrai si "l'existence ne peut pas être déterminée"? De toute évidence, l'existence peut être (et est en cours) déterminée par Fichier mais pas par Fichiers.

13
The Coordinator

En ce qui concerne la raison pour laquelle il peut y avoir une différence entre les deux, comparez leur documentation:

File.exists (): Renvoie true si et seulement si le fichier ou le répertoire désigné par ce chemin abstrait existe; faux sinon.

Files.exists (): renvoie true si le fichier existe; false si le fichier n'existe pasou si son existence ne peut être déterminée.

Cela pourrait éventuellement expliquer la différence entre les deux, peut-être que Files éprouve des difficultés à vérifier l’existence du fichier.

Par exemple, sous Linux, il est possible de configurer des autorisations de répertoire et de fichier de manière à pouvoir ouvrir un fichier existant mais non voir existant (en supprimant les droits de lecture sur le répertoire du fichier). est en laissant les autorisations de fichier plus ouvertes).

Selon plusieurs éléments de la documentation Oracle , Files.exists() ne renvoie true que si le fichier est vérifié.

Une valeur de retour de false fait pas signifie qu'elle n'existe pas.

Ils vous suggèrent d’utiliser exists() et notExists() pour couvrir les trois possibilités, par exemple:

if (Files.exists(fspec)) {
    System.out.println("It exists!");
else if (Files.notExists(fspec)) {
    System.out.println("It does not exist!");
else
    System.out.println("I have no idea!");

Cela couvre les trois possibilités d’état de fichier couvertes dans le lien ci-dessus:

  • Le fichier est vérifié pour exister.
  • Le fichier est vérifié pour ne pas exister.
  • Le statut du fichier est inconnu. Ce résultat peut se produire lorsque le programme n'a pas accès au fichier.
5
paxdiablo

j'ai eu le même problème, mais ton hack ne m'a pas aidé. Lorsque le fichier existait réellement, toutes les méthodes me renvoyaient false:

Files.exists(path) = false, 
path.toFile().exists() = false, 
Files.notExists(path) = true, 
Files.exists(path) || path.toFile().exists() = false

Mais si à ce moment dans l'explorateur un répertoire réseau contenant ce fichier était ouvert, alors son existence était correctement gérée

J'ai résolu ce problème en créant un nouveau fichier dans le répertoire (puis en le supprimant):

Files.createFile(Paths.get(path.getParent().toString(), "test"));

Après cette commande, apparemment, Windows met à jour les informations sur le dossier