File.exists () gibt false zurück, wenn eine Datei vorhanden ist

89

Ich bin auf einen Fehler gestoßen, hinter dem ich keine Logik zu finden scheint. Ich habe dieses Dateiobjekt, das wie folgt erstellt wird:

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

Ich mache file.exists()es dann und es kehrt zurück false(!?). Wenn die Datei nicht gefunden wird, melde ich mich f.getAbsolutePath()bei einer Datei an. Wenn ich mir den Weg ansehe, scheint es in Ordnung zu sein. Ich kann den vollständigen Pfad kopieren und in das "Ausführen" -Fenster in Windows einfügen und die Datei wird einwandfrei geöffnet.

Die Datei ist jederzeit vorhanden und wird während der Ausführung meiner Anwendung weder gelöscht noch geändert. Es befindet sich am lokalen Computer.

Dies scheint nur in bestimmten Situationen aufzutreten. Ich kann den Fehler jederzeit reproduzieren, bin mir jedoch sicher, dass der Pfad des Dateiobjekts durch die von mir durchgeführten Aktionen zur Reproduktion des Fehlers nicht geändert wird.

Was kann dazu führen file.exists(), dass false zurückgegeben wird? Hat dies etwas mit Berechtigungen oder Dateisperren usw. zu tun?

atsjoo
quelle
Ist es also möglich, aus der Datei zu lesen, auch wenn exist () false zurückgibt?
Harry Lime
Ja, ich kann aus der Datei lesen, auch wenn exist () false zurückgibt.
Atsjoo
1
Was genau wird benötigt, um den Fehler zu reproduzieren?
user85421
1
Dies befindet sich in einer Anwendung, die Funktionen aufruft, die in matlab geschrieben und in die Java-Anwendung kompiliert wurden. Es scheint, als würden Matlab-Funktionen, die das "aktuelle Verzeichnis" ändern, das Problem verursachen. Ich verwende den absoluten Pfad beim Erstellen des Dateiobjekts, daher sollte dies kein Problem sein - wie auch immer es scheint. Ich habe natürlich den absoluten Pfad des Dateiobjekts überprüft und er ist korrekt (genauso wie vor der Änderung des aktuellen Verzeichnisses durch die Matlab-Funktion).
Atsjoo
7
Arbeiten Sie zufällig gegen ein Remote-Verzeichnis (z. B. einen NFS-Mount)?
Tomer Gabel

Antworten:

41

Ich sehe die folgende Situation unter Windows 7:

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

Die fragliche Datei ist "var \ log". Der absolute Pfad bezieht sich auf eine vorhandene Datei, die sich in einem normalen Unterverzeichnis befindet (kein virtueller Speicher). Dies ist aus der IDE ersichtlich.

Roman Zenka
quelle
16
Ich habe es gerade herausgefunden: bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097 Anscheinend werden die in der Datei ausgeführten Vorgänge für das aktuelle Verzeichnis aufgelöst, während getAbsolutePath gegen user.dir aufgelöst wird. Wenn diese beiden Pfade nicht übereinstimmen, erhalten Sie widersprüchliche Ergebnisse. Teuflisch!
Roman Zenka
3
Ich habe genau das gleiche Problem, mit dem ich versucht habe, mit beiden Methoden zu überprüfen, ob eine Datei vorhanden ist, und trotzdem werde ich nur unter Windows 7 falsch! Irgendeine Idee?
Dejell
@ Odelya: Welche IDE verwenden Sie? Auf was ist dein -Duser.dir eingestellt? Mein Problem wurde dadurch verursacht, dass -Duser.dir auf ein anderes Verzeichnis als das aktuell funktionierende eingestellt wurde.
Roman Zenka
1
Für alle, die an einem dynamischen Webprojekt arbeiten und mit file.exists () eine Ausnahme auslösen, verwenden Sie file.getAbsoluteFile (). Exists (), um nach Dateien im WEB-INF-Verzeichnis zu suchen (allgemeiner Tipp, nicht Windows 7-spezifisch ).
PS
Erwägen
17

Es scheint einen Unterschied zu geben, wie der Pfad in Java angegeben wird.

Zum Beispiel, wenn der Dateipfad wie folgt angegeben file:/C:/DEV/test.txtist

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

wird zurückkehren false. Der Pfad funktioniert möglicherweise im Explorer oder im Browser, ist jedoch eine URL und kein absoluter Dateipfad.

Auf der anderen Seite, wenn der Dateipfad wie C:/DEV/test.txtdamals angegeben ist

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

wird zurückgegeben, trueda der Pfad keine URL ist, sondern ein absoluter Pfad.

Mit Spring Framework ist genau das der ResourceUtils.getFile(filename)Fall - wobei der Name entweder eine URL oder der absolute Dateipfad sein kann.

Garima Bathla
quelle
5
Ich würde nicht erwarten file:/C:/DEV/test.txt, als Pfadname zu arbeiten. Es ist eine URL, kein Pfadname. Während einige Leute diesen Fehler machen, gibt es keine Beweise dafür, dass das OP ...
Stephen C
15

Wenn der Prozess nicht über Berechtigungen verfügt, um festzustellen, ob eine Datei vorhanden ist, wird false zurückgegeben. Es ist möglicherweise möglich, eine Datei zu öffnen, aber nicht mit normalen Methoden festzustellen, ob sie vorhanden ist.

Tom Hawtin - Tackline
quelle
20
Interessant. Können Sie das näher erläutern? Welche spezifischen Berechtigungen haben Sie im Sinn?
Clément
Hier kann java.nio.file.AccessDeniedException die Fähigkeit blockieren, die Existenz von Dateien / Verzeichnissen zu erreichen. Wenn Sie beispielsweise das Verzeichnis in FAR oder einem anderen Datei-Explorer geöffnet lassen, dann das Verzeichnis mit allen verschachtelten Dateien löschen und die Existenz dieses Verzeichnisses überprüfen, können Sie AccessDeniedException (erweitert IOException) für temporäre Dateien erhalten, die für Sie aufbewahrt werden. In diesem Fall gibt Files.exists für IOException false zurück.
Beluha
11

Die obigen Antworten haben in meinem Fall nicht geholfen. Wie oben erwähnt, hatte ich:

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

Die Hauptursache dafür war, dass der Windows 7- Computerbesitzer die Registrierung für CMD so geändert hatte, dass ein Befehl zum Starten in einem bestimmten Verzeichnis für die Arbeit mit Python automatisch ausgeführt wurde. Diese Änderung hat den Java 1.6- Code verkrüppelt, der offenbar CMD unter Windows für bestimmte Dateivorgänge verwendet, z exists(). Das Problem wurde behoben, indem der Autorun aus der Registrierung entfernt wurde.

Karl Lew
quelle
1
3,5 Jahre später stieß ich auf das gleiche Problem. Ich hatte ein Autorun-Skript eingerichtet, um Umgebungsvariablen bei jedem Start von cmd.com zu konfigurieren. Das aktuelle Verzeichnis wurde nicht einmal geändert - nur einige Doskey-Makros und einige Umgebungsvariablen. Ich habe den Autorun entfernt und die Befehle in der Datei einfach manuell ausgeführt, und plötzlich funktioniert File.exists () korrekt.
Homr Zodyssey
1
OMG, es funktioniert wirklich (beide), ich habe nur dumm nach der falschen Datei gesucht und bin auf diese Frage gestoßen, um herauszufinden, warum keiner von ihnen für mich funktioniert :) Übrigens, es scheint, dass die ()in der zweiten Zeile danach fehlen exists; )
RAM237
3

Natürlich gibt es eine Reihe möglicher Ursachen, und die vorherigen Antworten dokumentieren sie gut, aber hier ist, wie ich dies in einem bestimmten Fall gelöst habe:

Ein Schüler von mir hatte dieses Problem und ich riss mir fast die Haare aus, um es herauszufinden. Es stellte sich heraus, dass die Datei nicht existierte, obwohl sie so aussah. Das Problem war, dass Windows 7 so konfiguriert war, dass "Dateierweiterungen für bekannte Dateitypen ausgeblendet werden". Dies bedeutet, dass wenn die Datei den Namen "data.txt" zu haben scheint, ihr tatsächlicher Dateiname "data.txt.txt" ist.

Hoffe, das hilft anderen, sich Haare zu sparen.

petehern
quelle
Ich glaube nicht, dass dies in meinem Fall das Problem war. Wie in meiner Frage erwähnt: "Ich kann den vollständigen Pfad kopieren und in das" Ausführen "-Fenster in Windows einfügen und die Datei wird einwandfrei geöffnet.", Was bedeutet, dass die Datei tatsächlich vorhanden ist.
Atsjoo
3

Der new FileBefehl erstellt lediglich eine Instanz einer Datei unter Verwendung des angegebenen Pfadnamens. Es wird keine Datei auf der Festplatte erstellt.

Wenn du sagst

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

Dies kann nur dann true zurückgeben, wenn eine Datei mit demselben Pfad vorhanden war. Wenn Sie nach derselben Datei suchen möchten, die in der ersten Zeile deklariert wurde, müssen Sie sie möglicherweise auf diese Weise verwenden.

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

Nun wird dies wahr zurückgeben.

R1234
quelle
kleine Erklärung: Jeder Aufruf des Konstruktors unter Verwendung eines neuen Schlüsselworts erzeugt ein Objekt - genau wie in diesem Fall ein von Class beschriebenes Objekt, dessen Name Datei ist! also keine Instanz von File! = Deskriptoren :)
ceph3us
3

Wenn Sie nicht jedes Mal, wenn Sie eine Methode aufrufen müssen, getAbsoluteFile () -Aufrufe verarbeiten möchten, erstellen Sie Ihre Dateiinstanz besser bereits mit einem absoluten Pfad. Dies sollte den Trick tun:

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

Ich schlage vor, es mit einem Try-Catch-Block zu umgeben, übrigens.

Fran Marzoa
quelle
3

Um das Problem zu verallgemeinern, tritt das Problem beim Konvertieren von URL / URI in lokale Pfade auf.

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

Hoffe das hilft.

Arun
quelle
2

Wenn ["Erweiterungen für bekannte Dateitypen ausblenden."] Aktiviert ist, öffnen Sie "t.txt.txt", wenn Sie "t.txt" in [Explorer] / [Windows ausführen] eingeben, programmgesteuert jedoch nicht.

ich auch
quelle
1
Ich hatte dieses Problem und das Problem war, dass ich in C: \ test eine txt-Datei mit dem Namen 'testFile.txt' erstellt habe. Ich habe auf diese Datei mit dem Pfad C: \ test \ testFile.txt verwiesen, was nicht funktioniert hat. Es war, weil die Datei tatsächlich als testFile.txt.txt gespeichert worden war, daher die Abstimmung über die obige Lösung (alte Frage, aber keine akzeptierte Antwort!)
Theblacknight
Gott Windows saugt so viel.
Aafc
0

Gute Antworten an alle. Ich habe festgestellt, dass dies ein Problem mit dem Zugriff von Java auf das Stammverzeichnis C:unter Windows zu sein scheint . Jedes andere Verzeichnis sollte in Ordnung sein, aber aus irgendeinem Grund, insbesondere durch Erwähnung C:\oder C:oder C:/möglicherweise als Fehler. Ich habe dieses sehr ähnliche Problem gelöst, indem ich die Erwähnung abgefangen new File("C:");und durch eine neue ersetzt habe, File(System.getProperty("file.separator"));oder Sie sollten in der Lage sein, "\" fest zu codieren, anstatt "c:" als Dateiverzeichnis zu sagen, und es könnte funktionieren. Nicht elegant, aber ich habe die Arbeit für dieses Projekt erledigt.

Ich hoffe, es hilft. Könnte nicht die richtige Lösung sein, aber zumindest hat es bei mir funktioniert. Ich bin dran JRE 1.6, Win 7. Prost!

Respektvoll,

@ Carpenter1010

Code Carpenter
quelle
0

Wenn die Situation, in der es fehlschlägt, darin besteht, es als ein anderer Benutzer auszuführen, und Sie unter Windows Vista / Windows 7 arbeiten, kann dies durch VirtualStore verursacht werden, den Mechanismus, bei dem Windows einen nicht privilegierten Benutzer "schreiben" lässt, wo dies normalerweise nicht möglich ist. Die Änderungen werden jedoch in "% USERPROFILE% \ AppData \ Local \ VirtualStore \" gespeichert, die für jedes Benutzerkonto privat sind.

Kjetil Jörgensen
quelle
1
Ich
laufe unter Windows XP
0

Als nichts von oben für mich funktionierte, versuchte ich es

filePath = filePath.trim();

Dadurch wird Ihre Saite von unerwünschten Zeichen befreit

Asim
quelle
0

Ich bin kürzlich auf dasselbe Problem gestoßen. Ich habe Netbeans deinstalliert, den Netbeans-Ordner vom Laufwerk C gelöscht, Programme, Updates, Programmdaten praktisch überall gelöscht. Dann neu installieren. Funktioniert jetzt gut. Vergessen Sie nicht, den NetBeans-Projektordner zu sichern, bevor Sie die oben genannten Aktionen ausführen.

Ich hoffe es hilft.

Evaboy
quelle
0

Bei einigen IDEs (möglicherweise) und / oder bei einigen Betriebssystemen (z. B. Fenster) haben sie standardmäßig keinen Schreibzugriff auf Dateien. Wenn Sie also versuchen, file.exists () auszuführen, wird Ihnen false angezeigt. Um dies zu beheben, gehen Sie wie folgt vor

Wenn Ihre Referenzvariable für Datei f ist, Beispiel: Datei f = neue Datei ("Pfad");

Um es zum Laufen zu bringen, wählen Sie f mit der Maus und gehen Sie dann zu Suchmenü> Schreibzugriff> Arbeitsbereich. Hoffentlich klappt es.

Gautam Anand
quelle
-2

Ich denke, Sie sollten stattdessen Backslash verwenden, wie folgt:

Datei file = neue Datei ("C: \\ Benutzer \\ Dienstprogramme \\ Daten \\ someTextFile.txt"); (zwei Backslashes, kein Tippfehler)

Sollte das Problem lösen :)

Hussein Maziad
quelle
3
Ich denke, das Problem hängt eher mit dem absoluten Pfad als mit dem relativen Pfad zusammen. Der Schrägstrich ist in Java auch für Windows-Pfade gültig.
рüффп