2016-03-25 9 views
19

Als ich eine java.lang.File-Klasse mit dem Code File file = new File("e:/"); bekam, bekam ich natürlich eine File-Klasse, die das e: \ -Verzeichnis darstellt.Ist das ein Fehler in Java jdk?

Aber wenn ich eine File-Klasse mit Code File file = new File("e:"); bekommen habe und ich gerade in das Laufwerk E :, dann habe ich eine File-Klasse repräsentiert aktuelles Verzeichnis.

Angenommen, ich bin im Verzeichnis E: \ dir \, und dieses Verzeichnis hat eine Datei namens Test.java. Es ist Inhalt ist:

import java.io.File; 
public class Test { 
    public static void main(String[] args) { 
     File file = new File("e:"); 
     File[] files = file.listFiles(); 
     for(File f: files){ 
      System.out.println(f + " " + f.exists()); 
     } 
    } 
} 

Öffnen Sie das cmd-Tool und in das Verzeichnis e navigieren: \ dir, führen Sie den folgenden Befehl in es:

E:\dir> javac Test.java 
E:\dir> java Test 

Ich habe:

e:\Test.class false 
e:\Test.java false 

Ist das ein Java Jdk Bug?


Zusätzliche Informationen aus @JimGarrison:

lief ich diesen Code

public class Foo3 
{ 
    public static void main(String[] args) throws Exception 
    { 
     File f = new File("D:"); 
     System.out.println(f.getCanonicalPath()); 
     for (File x : f.listFiles()) 
      System.out.println(x + " " + x.getCanonicalPath() + " " + x.getAbsolutePath() + " " + x.exists() + " " + x.getAbsoluteFile().exists()); 
    } 
} 

in Eclipse (die auf meinem D lebt: Laufwerk) und bekam die folgende Ausgabe:

D:\dev\src\pdxep 
D:\.classpath D:\dev\src\pdxep\.classpath D:\dev\src\pdxep\.classpath false true 
D:\.project D:\dev\src\pdxep\.project D:\dev\src\pdxep\.project false true 
D:\.settings D:\dev\src\pdxep\.settings D:\dev\src\pdxep\.settings false true 
D:\gallery D:\dev\src\pdxep\gallery D:\dev\src\pdxep\gallery false true 
D:\pom.xml D:\dev\src\pdxep\pom.xml D:\dev\src\pdxep\pom.xml false true 
D:\src D:\dev\src\pdxep\src D:\dev\src\pdxep\src false true 
D:\target D:\dev\src\pdxep\target D:\dev\src\pdxep\target false true 

Was bestätigt, dass etwas lustiges vor sich geht.

Java Bug 8130462 scheint verwandt zu sein, da es mit relativen vs absolute Pfade speziell in Windows zu tun hat.

+1

Sehr neugierig. Ich kann das Problem auch reproduzieren. –

+0

Ich habe das Programm wie oben beschrieben ausgeführt (obwohl ich den Klassennamen in TestFile geändert habe) und die erwartete Ausgabe (Dateien und Verzeichnisse usw.) für das Laufwerk e: (Windows 10) erhalten. Java 1.8.0_72 ausführen. @ JimGarrison ist es interessant, dass Sie das Problem reproduziert. Lief es sowohl innerhalb von Eclipse als auch an der Kommandozeile. Der einzige Unterschied ist, dass ich einen Paketnamen hatte, also war es java -cp ./bin package.TestFile – KevinO

+0

Wenn Sie in einem Debugger laufen und bei der 'println' stoppen, können Sie sehen, dass es einen Unterschied zwischen dem Pfad und dem kanonischen Pfad gibt. Die Ausgabe, die Sie sehen (das aktuelle Verzeichnis fehlt), scheint das zu sein, was verwendet wird, um nach der Datei zu suchen, aber das Drucken des kanonischen Pfads enthält das aktuelle Verzeichnis. Sicher sieht es aus wie ein Bug (wahrscheinlich in der Implementierung des Windows-Dateisystem-Providers). Das Erstellen einer Datei aus einer expliziten vollständigen Pfadzeichenfolge hat dieses Problem nicht. –

Antwort

1

Der erste Teil zum Erhalten eines File, das das aktuelle Arbeitsverzeichnis mit Code File file = new File("e:"); darstellt, ist kein Fehler. Es ist ein Windows "relativer Laufwerkspfad". Dies ist ein Pfad relativ zum aktuellen Arbeitsverzeichnis im angegebenen Laufwerk. (Ja, habe Windows einen anderen Arbeitsdirektor pro Laufwerk)

Das Problem ist, dass Java fügt fälschlicherweise ein \ nach dem Laufwerkbuchstabe auf dem Weg, die den Weg aussehen wie ein absoluter Pfad macht, und gibt zu Unrecht false auf file.exists() wahrscheinlich deswegen.

Allerdings löst Java den kanonischen Pfad und den absoluten Pfad korrekt auf und gibt True unter x.getAbsoluteFile().exists() korrekt zurück. Java gibt auch den Inhalt der CWD in file.listFiles() korrekt zurück, wie Sie in Ihrem Beispielcode festgestellt haben.

Ich habe einen alten Bug in der Datenbank gefunden, der dazu JDK-5066567 oder zumindest sehr ähnlich ist. Es wurde im Jahr 2004 erstellt und auf "In Arbeit" 2013 gesetzt und der aktuelle Beauftragte ist "Inaktiv", also glaube ich nicht, dass wir bald eine Lösung dafür finden werden, wenn überhaupt.

Also um Ihre Frage zu beantworten, würde ich sagen, ja, es ist ein Fehler.

Es scheint jedoch, dass es besser in java.nio.file.Path gehandhabt wird. Wenn es möglich ist, stattdessen das java.nio.file.*-Paket in Ihrem Anwendungsfall zu verwenden, könnte dies eine akzeptable Problemumgehung sein.

1

Es ist kein Fehler.

  • E:/ bedeutet, dass Sie angeben, sowohl ein Laufwerk und ein Verzeichnis

  • E: bedeutet, dass Sie nur ein Laufwerk angeben, wird das Verzeichnis auf den Standardwert links.

Hinweis: Nun, was Leute denken, als aktuelle Verzeichnis ist eigentlich Standard Verzeichnis. d. h., was standardmäßig angewendet wird, wenn keiner angegeben ist. Es ist genauso, wenn Sie das Laufwerk überhaupt nicht angeben, wird die Standardeinstellung (aktuelle Standardeinstellung) angewendet.

So funktioniert es bei den meisten Dateisystemen.

+0

Interessant über das Standardverzeichnis, wusste das nicht. Können Sie einen Link bereitstellen, um mehr darüber zu lesen? File.exists() sollte trotzdem trotzdem true zurückgeben, und das ist der Fehler, also tut es mir leid, aber in dieser Hinsicht denke ich, dass Sie falsch liegen. Oder haben Sie eine Erklärung für dieses Verhalten? – gustf

+0

'Current working directory' ist seit Jahrzehnten der Begriff, und deshalb wird zum Beispiel der 'pwd' Befehl nicht' pdd' geschrieben. Es macht nicht viel Sinn, den Namen jetzt zu ändern. – EJP

+0

@EJP, dann können Sie erklären, warum in ehrwürdigen VMS-Befehlssprache (genannt DCL), der CD-Befehl ist tatsächlich 'set default'. Und BTW, muss ich Sie daran erinnern, dass der Chefarchitekt von Windows Dave Cuttler, auch der Architekt von VMS war? –