Risposte:
Considera 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 virata 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 collegamenti simbolici (su unix).
Nota anche 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'output sarà piuttosto diverso:
C:\Windows
C:\Windows\System32\drivers
C:\temp\file.txt
tratti di un percorso canonico: la directory temporanea potrebbe essere un collegamento software del file system o un collegamento reale (una giunzione in NTFS) e file.txt potrebbe essere un collegamento software. Non so se i file system possano distinguere i collegamenti reali ai file.
getAbsolutePath()
posto di getCanonicalPath()
. Sembra persino migliore perché quello canonico risolve automaticamente quelle ../
parti.
getCanonicalPath
getta un IOException
po ' getAbsolutePath
non lo fa, se questa è una considerazione.
Il modo migliore che ho trovato per avere un'idea di cose come questa è provarle:
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) {}
}
}
Il tuo output sarà simile a:
test\..\.\file.txt
C:\projects\sandbox\trunk\test\..\.\file.txt
C:\projects\sandbox\trunk\file.txt
Quindi, getPath()
ti dà il percorso basato sull'oggetto File, che può essere o non essere relativo; getAbsolutePath()
ti dà un percorso assoluto per il file; e getCanonicalPath()
ti dà il percorso assoluto univoco al file. Si noti che esiste un numero enorme di percorsi assoluti che puntano allo stesso file, ma solo un percorso canonico.
Quando usarli? Dipende da cosa stai cercando di realizzare, ma se stavi cercando di vedere se dueFiles
puntano allo stesso file su disco, potresti confrontare i loro percorsi canonici. Solo un esempio.
but if you were trying to see if two Files are pointing at the same file on disk
Come? esempio per favore?
In breve:
getPath()
ottiene la stringa del percorso con cui è File
stato costruito l' oggetto e può essere la directory corrente relativa.getAbsolutePath()
ottiene la stringa del percorso dopo averla risolta nella directory corrente se è relativa, 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 i mezzi canonici per fare riferimento all'oggetto del file system a cui punta.Inoltre, ognuno di questi ha un equivalente File che restituisce l' File
oggetto corrispondente .
getPath()
restituisce il percorso utilizzato per creare l' File
oggetto. Questo valore di ritorno non viene modificato in base alla posizione in cui viene eseguito (i risultati seguenti sono per Windows, i separatori sono ovviamente diversi 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()
risolverà il percorso in base alla posizione o all'unità di esecuzione. 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 hai "." Nel percorso, questi verranno generalmente rimossi.
Quanto a quando usarli. Dipende da cosa stai cercando di ottenere. getPath()
è utile per la portabilità. getAbsolutePath()
è utile per trovare la posizione del file system ed getCanonicalPath()
è particolarmente utile per verificare se due file sono uguali.
getCanonicalPath() is particularly useful to check if two files are the same.
La cosa più grande da tenere a mente è che la File
classe cerca di rappresentare una visione di ciò che a Sun piace chiamare "nomi gerarchici" (fondamentalmente un percorso come c:/foo.txt
o /usr/muggins
). Questo è il motivo per cui crei file in termini di percorsi. Le operazioni che stai descrivendo sono tutte operazioni su questo "nome percorso".
getPath()
recupera il percorso con cui è stato creato il file ( ../foo.txt
)getAbsolutePath()
recupera il percorso con cui è stato creato il file, ma include informazioni sulla directory corrente se il percorso è relativo ( /usr/bobstuff/../foo.txt
)getCanonicalPath()
tenta di recuperare una rappresentazione univoca del percorso assoluto del file. Questo elimina il riferimento indiretto da ".." e "." referenze ( /usr/foo.txt
).Nota dico tentativi : nel formare un Percorso canonico, la VM può lanciare un IOException
. Questo di solito si verifica perché sta eseguendo alcune operazioni del filesystem, ognuna delle quali potrebbe non riuscire.
Trovo che raramente ho bisogno di usare getCanonicalPath()
ma, se viene dato un file con un nome file che è in formato DOS 8.3 su Windows, come la java.io.tmpdir
proprietà System restituisce, questo metodo restituirà il nome file "completo".
Path.toAbsolutePath().normalize()
quale è una buona via di mezzo tra percorso canonico (reale) e percorso assoluto da solo.