web-dev-qa-db-fra.com

File.exists () renvoie false lorsque le fichier existe

J'ai rencontré un bug que je n'arrive pas à trouver de logique derrière. J'ai cet objet File, qui est créé comme ceci:

File file = new File("utilities/data/someTextFile.txt");

Je fais alors file.exists(), et il retourne false (!?). Si le fichier n'est pas trouvé, je connecte f.getAbsolutePath() à un fichier. Quand je regarde le chemin, ça semble OK. Je peux copier-coller le chemin complet dans la fenêtre "Exécuter" dans Windows et le fichier s'ouvre très bien.

Le fichier existe à tout moment et n'est ni supprimé ni modifié lors de l'exécution de mon application. Il est situé sur la machine locale.

Cela ne semble se produire que dans certaines situations. Je peux reproduire l'erreur à tout moment, mais je suis sûr que le chemin de l'objet fichier n'est pas modifié par les actions que je fais pour reproduire l'erreur.

Qu'est-ce qui peut faire que file.exists() retourne false? Cela a-t-il quelque chose à voir avec les autorisations ou les verrous de fichiers, etc.?

82
atsjoo

Je vois la situation suivante sur Windows 7:

file.exists() == false
file.getAbsoluteFile().exists() == true

Le fichier en question est "var\log", le chemin absolu fait référence à un fichier existant qui se trouve dans un sous-répertoire normal (pas un magasin virtuel). Cela se voit depuis l'IDE.

36
Roman Zenka

Il semble qu'il y ait une différence sur la façon dont le chemin est spécifié en Java.

Par exemple, si le chemin du fichier est spécifié comme file:/C:/DEV/test.txt Alors

File f = new File(filename);
f.exists();

renverra false. Le chemin peut fonctionner dans l'explorateur ou dans le navigateur, mais il s'agit d'une URL et non d'un chemin de fichier absolu.

Mais d'un autre côté, si le chemin du fichier est spécifié comme C:/DEV/test.txt Alors

File f = new File(filename);
f.exists();

renverra true car le chemin n'est pas une URL, mais c'est un chemin absolu.

Avec Spring Framework c'est exactement ce que fait ResourceUtils.getFile(filename) - où le nom peut être soit une URL soit le chemin absolu du fichier.

16
Garima Bathla

Si le processus n'a pas l'autorisation de dire si un fichier existe, il retournera false. Il peut être possible d'ouvrir un fichier, mais pas de dire par des méthodes normales s'il existe.

15

Les réponses ci-dessus n'ont pas aidé dans mon cas. Comme indiqué ci-dessus, j'avais:

file.exists() => false
file.getAbsoluteFile().exists => true

La cause principale de ceci était que le propriétaire de la machine Windows 7 avait modifié le registre pour CMD afin qu'il lance automatiquement une commande à lancer dans un répertoire spécifique pour travailler avec Python. Cette modification a paralysé le code Java 1.6 qui utilise apparemment CMD on Windows pour certaines opérations sur les fichiers, telles que comme exists(). L'élimination de l'exécution automatique du registre a résolu le problème.

11
Karl Lew

Le new File commande crée simplement une instance d'un fichier en utilisant le nom de chemin donné. Il ne crée pas réellement de fichier sur le disque dur.

Si tu le dis

File file = new File ("path");
file.exists() 

Cela ne peut retourner vrai que s'il y avait un fichier existant avec le même chemin. Si vous aviez l'intention de vérifier le même fichier déclaré dans la première ligne, vous devrez peut-être l'utiliser de cette façon.

File file = new File ("path");
file.createNewFile();
file.exists();

Maintenant, cela reviendra vrai.

3
R1234

Si vous ne voulez pas traiter les appels getAbsoluteFile () chaque fois que vous devez appeler une méthode, vous feriez mieux de créer votre instance de fichier déjà avec un chemin absolu. Cela devrait faire l'affaire:

File file = new File("utilities/data/someTextFile.txt").getAbsoluteFile();

Je suggère de l'entourer d'un bloc try-catch, BTW.

3
Fran Marzoa

Évidemment, il existe un certain nombre de causes possibles et les réponses précédentes les documentent bien, mais voici comment j'ai résolu cela dans un cas particulier:

Un de mes élèves a eu ce problème et j'ai failli me déchirer les cheveux en essayant de le comprendre. Il s'est avéré que le fichier n'existait pas, même s'il avait l'air de l'être. Le problème était que Windows 7 était configuré pour "Masquer les extensions de fichier pour les types de fichiers connus". Cela signifie que si le fichier semble avoir le nom "data.txt", son nom de fichier réel est "data.txt.txt".

J'espère que cela aide les autres à se sauver des cheveux.

2
petehern

Lorsque ["Masquer les extensions pour les types de fichiers connus."] Est coché, les fenêtres ouvrent "txt.text" lorsque vous tapez "t.txt" dans [Explorer]/[exécuter les fenêtres] mais pas par programme.

1
metoo

Pour généraliser le problème, le problème se pose lors de la conversion URL/URI en chemins locaux.

Example: URL url = file:/D:/code%20repo%20sample/sample.txt

// To remove url reference
String localPath = url.getPath();  
> /D:/code%20repo%20sample/sample.txt

// Decoding reserved characters in url from hexadecimal to character
URLDecoder.decode(localPath, StandardCharsets.UTF_8.toString()); 
> /D:/code repo sample/sample.txt

J'espère que cela t'aides.

1
Arun

Bonnes réponses à tous. J'ai trouvé que cela semblait être un problème avec Java accédant au répertoire racine C: Sous Windows. Tout autre répertoire devrait être correct, mais pour une raison quelconque, mentionnant spécifiquement C:\ Ou C: Ou C:/ Peut donner une erreur. J'ai résolu ce problème très similaire en piégeant la mention dans new File("C:"); et en la remplaçant par une nouvelle fonction File(System.getProperty("file.separator")); ou vous devriez pouvoir coder en dur "\" au lieu de dire "c:" comme répertoire de fichiers et cela pourrait fonctionner. Pas élégant, mais j'ai fait le travail pour moi sur ce projet.

J'espère que ça aide. Ce n'est peut-être pas la bonne solution, mais au moins cela a fonctionné pour moi. Je suis sur JRE 1.6, Win 7. À votre santé!

Avec respect,

@ Carpenter1010

0
Code Carpenter

Quand rien d'en haut n'a fonctionné pour moi, j'ai essayé

filePath = filePath.trim();

Cela nettoiera votre chaîne de tout caractère indésirable

0
Asim

Si les situations où il échoue impliquent de l'exécuter en tant qu'un autre utilisateur, et que vous êtes sous Windows Vista/Windows 7, cela peut être dû à VirtualStore, le mécanisme par lequel Windows permet à un utilisateur non privilégié d '"écrire" à des endroits qu'il ne peut normalement pas. Les modifications sont cependant stockées dans "% USERPROFILE%\AppData\Local\VirtualStore \" qui sont privées pour chaque compte d'utilisateur.

0