2009-07-08 9 views

risposta

551

Considerare questi nomi di file:

C:\temp\file.txt - Questo è un percorso, un percorso assoluto, e un percorso canonico.

.\file.txt - Questo è un percorso. Non è né un percorso assoluto né un percorso canonico.

C:\temp\myapp\bin\..\\..\file.txt - Questo è un percorso e un percorso assoluto. Non è un percorso canonico.

Un percorso canonico è sempre un percorso assoluto.

La conversione da un percorso a un percorso canonico lo rende assoluto (di solito virano sulla directory di lavoro corrente, ad esempio ./file.txt diventa c:/temp/file.txt). Il percorso canonico di un file "purifica" il percorso, rimuovendo e risolvendo cose come ..\ e risolvendo i collegamenti simbolici (sugli unix).

Si noti inoltre il seguente esempio con nio.Paths:

String canonical_path_string = "C:\\Windows\\System32\\"; 
String absolute_path_string = "C:\\Windows\\System32\\drivers\\..\\"; 

System.out.println(Paths.get(canonical_path_string).getParent()); 
System.out.println(Paths.get(absolute_path_string).getParent()); 

Mentre entrambi i percorsi si riferiscono alla stessa posizione, l'uscita sarà molto diverso:

C:\Windows 
C:\Windows\System32\drivers 
+8

FWIW, non è un dato che 'C: \ temp \ file.txt' è un percorso canonico - la directory temp potrebbe essere un soft link del file system o un hard link (una giunzione in NTFS), e file.txt potrebbe essere un collegamento lento. Non so se i file system possano distinguere i collegamenti fisici ai file. Il percorso –

+1

non considera veramente quei problemi o l'esistenza di nessuno dei componenti, ma solo la sua sintassi. –

+0

Lo fa, il percorso canonico (a differenza del percorso normalizzato) colpisce il file system. – eckes

59

In breve:

  • getPath() ottiene la stringa di percorso che l'oggetto File stato costruito con, e potrebbe essere directory corrente relativa.
  • getAbsolutePath() ottiene la stringa di percorso dopo averlo risolto rispetto alla directory corrente se è relativo, risultando in un percorso completo.
  • getCanonicalPath() ottiene la stringa del percorso dopo aver risolto qualsiasi percorso relativo rispetto alla directory corrente e rimuove qualsiasi percorso relativo (. e ..) e qualsiasi collegamento al file system per restituire un percorso che il file system considera come canonico per fare riferimento al file system oggetto a cui punta.

Inoltre, ognuno di questi ha un equivalente File che restituisce l'oggetto File corrispondente.

105

Il modo migliore che ho trovato per avere un'idea di cose come questa è provarli:

import java.io.File; 
public class PathTesting { 
    public static void main(String [] args) { 
     File f = new File("test/.././file.txt"); 
     System.out.println(f.getPath()); 
     System.out.println(f.getAbsolutePath()); 
     try { 
      System.out.println(f.getCanonicalPath()); 
     } 
     catch(Exception e) {} 
    } 
} 

L'output sarà un po ' cosa come:

test\..\.\file.txt 
C:\projects\sandbox\trunk\test\..\.\file.txt 
C:\projects\sandbox\trunk\file.txt 

Quindi, getPath() ti dà il percorso in base all'oggetto file, che può o non può essere relativa; getAbsolutePath() fornisce un percorso assoluto per il file; e getCanonicalPath() fornisce il percorso assoluto univoco per il file. Si noti che esiste un numero enorme di percorsi assoluti che puntano allo stesso file, ma solo un percorso canonico.

Quando utilizzare ciascuno? Dipende da cosa stai cercando di realizzare, ma se stai cercando di vedere se due Files puntano allo stesso file sul disco, puoi confrontare i loro percorsi canonici. Solo un esempio

+6

È discutibile che Java abbia sbagliato l'implementazione di un percorso" assoluto "; in realtà avrebbe dovuto rimuovere qualsiasi elemento relativo del percorso in un percorso assoluto. La forma canonica rimuove quindi qualsiasi collegamento o giunzione FS nel percorso. –

+0

'ma se stavi cercando di vedere se due file puntano allo stesso file sul disco? Come? esempio per favore? – UnKnown

18

La grande cosa per ottenere la testa intorno è che la classe File cerca di rappresentare una visione di ciò sole come chiamare "percorsi gerarchici" (in pratica un percorso come c:/foo.txt o /usr/muggins). Questo è il motivo per cui si creano file in termini di percorsi. Le operazioni che stai descrivendo sono tutte operazioni su questo "percorso".

  • getPath() recupera il percorso che il file è stato creato con (../foo.txt)
  • getAbsolutePath() recupera il percorso che il file è stato creato con, ma include informazioni sulla directory corrente se il percorso è relativo (/usr/bobstuff/../foo.txt)
  • getCanonicalPath()tentativi per recuperare una rappresentazione univoca del percorso assoluto del file. Questo elimina l'indirezione da ".." e "." riferimenti (/usr/foo.txt).

Nota dico tentativi - a formare un percorso canonico, il VM può gettare un IOException. Questo di solito si verifica perché sta eseguendo alcune operazioni sul filesystem, ognuna delle quali potrebbe fallire.

31

getPath() restituisce il percorso utilizzato per creare l'oggetto File. Questo valore non viene modificato in base alla posizione in cui viene eseguito (risultati seguenti sono per finestre, separatori sono ovviamente diverse altrove)

File f1 = new File("/some/path"); 
String path = f1.getPath(); // will return "\some\path" 

File dir = new File("/basedir"); 
File f2 = new File(dir, "/some/path"); 
path = f2.getPath(); // will return "\basedir\some\path" 

File f3 = new File("./some/path"); 
path = f3.getPath(); // will return ".\some\path" 

getAbsolutePath() sarà risolvere il percorso in base alla posizione esecuzione o unità. Quindi, se eseguito da c:\test:

path = f1.getAbsolutePath(); // will return "c:\some\path" 
path = f2.getAbsolutePath(); // will return "c:\basedir\some\path" 
path = f3.getAbsolutePath(); // will return "c:\test\.\basedir\some\path" 

getCanonicalPath() dipende dal sistema. Risolverà la posizione unica rappresentata dal percorso. Quindi, se nel percorso sono presenti "." S, in genere verranno rimossi.

Per quanto riguarda quando usarli. Dipende da ciò che stai cercando di ottenere. getPath() è utile per la portabilità. getAbsolutePath() è utile per trovare il percorso del file system e getCanonicalPath() è particolarmente utile per verificare se due file sono uguali.

+0

puoi darmi qualche esempio di questo? 'getCanonicalPath() è particolarmente utile per verificare se due file sono uguali – UnKnown

3

Trovo che raramente ho bisogno di usare getCanonicalPath() ma, se viene fornito un file con un nome di file in formato DOS 8.3 su Windows, come la proprietà di sistema java.io.tmpdir, questo metodo restituirà il nome file "completo".

Problemi correlati