2016-03-25 18 views
19

Quando ho ottenuto una classe java.lang.File con il codice File file = new File("e:/");, ovviamente ho ottenuto una classe File rappresentata nella directory e: \.Si tratta di un bug in java jdk?

Ma se ho ottenuto una classe File con il codice File file = new File("e:"); e io solo nell'unità E :, quindi ho ottenuto una classe File rappresentata directory corrente.

Assumendo che sia nella directory E: \ dir \, e questa directory abbia un file denominato Test.java. E 'il contenuto è:

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()); 
     } 
    } 
} 

Aprire lo strumento cmd e passare alla directory e: \ dir, eseguire il seguente comando in esso:

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

ho ottenuto:

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

È un bug java jdk?


Ulteriori informazioni da @JimGarrison:

mi sono imbattuto questo codice

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 (che vive sul mio D: azionamento) ed ha ottenuto il seguente risultato:

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 

Che conferma che sta succedendo qualcosa di divertente.

Java Bug 8130462 sembra essere correlato in quanto ha a che fare con percorsi relativi rispetto assoluto in particolare in Windows.

+1

Molto curioso. Posso riprodurre il problema pure. –

+0

Ho eseguito il programma come scritto sopra (anche se ho modificato il nome della classe in TestFile) e ho ricevuto l'output previsto (file e directory elencati, ecc.) Per l'unità e: (Windows 10). Esecuzione di Java 1.8.0_72. @ JimGarrison è interessante che tu abbia riprodotto il problema. L'ho eseguito sia da Eclipse che dalla riga di comando. L'unica differenza è che avevo il nome di un pacchetto, quindi era java -cp ./bin package.TestFile – KevinO

+0

Se si esegue un debugger e ci si ferma su 'println', si vede che c'è una differenza tra il percorso e il percorso canonico. L'output che vedi (manca la directory corrente) sembra essere quello che viene usato per cercare il file, ma la stampa del percorso canonico include la directory corrente. Certo sembra un bug (probabile nell'implementazione del provider di filesystem di Windows). La creazione di un file da una stringa di percorso completo esplicita non presenta questo problema. –

risposta

1

La prima parte relativa all'ottenere un File che rappresenta la directory di lavoro corrente con il codice File file = new File("e:"); non è un bug. È un "percorso relativo all'unità" di Windows. Ovvero, un percorso relativo alla directory di lavoro corrente nell'unità specificata. (Sì, Windows ha un direttore di lavoro diverso per ogni unità)

Il problema è che Java aggiunge erroneamente un \ dopo la lettera di unità nel percorso che rende il look percorso come un percorso assoluto, e restituisce a torto false su file.exists() probabilmente per questo motivo

Tuttavia, Java risolve correttamente il percorso canonico e il percorso assoluto e restituisce correttamente true su x.getAbsoluteFile().exists(). Java restituisce correttamente anche il contenuto dello CWD in file.listFiles() come notato nel codice di esempio.

Ho trovato un vecchio bug nel database che JDK-5066567 su questo o almeno molto simile a questo. È stato creato nel 2004 e impostato su "In corso" nel 2013 e l'attuale assegnatario è "Inattivo", quindi non credo che vedremo presto una soluzione per questo, se mai.

Quindi per rispondere alla tua domanda, direi di si, è un bug.

Tuttavia, sembra che sia gestito meglio in java.nio.file.Path. Quindi, se è possibile utilizzare il pacchetto java.nio.file.* nel proprio caso d'uso, potrebbe essere una soluzione accettabile.

1

Non è un bug.

  • E:/ significa che si specifica sia un drive e una directory

  • E: significa che si specifica solo un disco, la directory è lasciato al valore di default.

Nota: Ora che cosa la gente pensa di come directory corrente è in realtà predefinita directory. Ad esempio, cosa viene applicato per impostazione predefinita quando non viene specificato nessuno. È lo stesso se non si specifica affatto l'unità, verrà applicata l'impostazione predefinita (impostazione predefinita corrente).

Questo è il modo in cui funziona sulla maggior parte dei file system.

+0

Interessante sulla directory di default, non lo sapevo. Potrebbe fornire un link per saperne di più su questo. Tuttavia, file.exists() dovrebbe ancora restituire true a prescindere da ciò, e questo è il bug, quindi mi dispiace ma a tale riguardo penso che tu abbia torto. O hai una spiegazione di questo comportamento? – gustf

+0

'Current working directory' è il termine usato da decenni, ed è per questo che ad esempio il comando 'pwd' non è scritto' pdd'. Non ha molto senso tentare di cambiare il nome ora. – EJP

+0

@EJP, allora potrebbe essere che tu possa spiegare perché nel venerabile linguaggio di comando di VMS (chiamato DCL), il comando cd è in realtà 'set default'. E a proposito, devo ricordarti che il capo architetto di Windows era Dave Cuttler, anche l'architetto di VMS? –

Problemi correlati