Quelle est la différence entre getPath()
, getAbsolutePath()
et getCanonicalPath()
en Java?
Et quand est-ce que je les utilise?
Considérez ces noms de fichiers:
C:\temp\file.txt
- C'est un chemin, un chemin absolu et un chemin canonique.
.\file.txt
- C'est un chemin. Ce n'est ni un chemin absolu ni un chemin canonique.
C:\temp\myapp\bin\..\\..\file.txt
- C'est un chemin et un chemin absolu. Ce n'est pas un chemin canonique.
Un chemin canonique est toujours un chemin absolu.
La conversion d'un chemin en un chemin canonique le rend absolu (généralement, le point de départ du répertoire de travail en cours, par exemple, ./file.txt
devient c:/temp/file.txt
). Le chemin canonique d'un fichier "purifie" simplement le chemin, en supprimant et en résolvant des choses comme ..\
et en résolvant des liens symboliques (sous Unix).
Notez également l'exemple suivant avec 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());
Bien que les deux chemins se rapportent au même emplacement, la sortie sera très différente:
C:\Windows
C:\Windows\System32\drivers
Le meilleur moyen que j'ai trouvé pour avoir une idée de ce genre de choses est de l'essayer:
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) {}
}
}
Votre sortie sera quelque chose comme:
test\..\.\file.txt
C:\projects\sandbox\trunk\test\..\.\file.txt
C:\projects\sandbox\trunk\file.txt
Donc, getPath()
vous donne le chemin en fonction de l'objet File, qui peut être relatif ou non. getAbsolutePath()
vous donne un chemin absolu vers le fichier; et getCanonicalPath()
vous donne le chemin absolu unique du fichier. Notez qu'il existe un grand nombre de chemins absolus qui pointent vers le même fichier, mais un seul chemin canonique.
Quand utiliser chacun? Cela dépend de ce que vous essayez d'accomplir, mais si vous essayez de voir si deux Files
pointent sur le même fichier sur le disque, vous pouvez comparer leurs chemins canoniques. Juste un exemple.
En bref:
getPath()
obtient la chaîne de chemin d'accès avec laquelle l'objet File
a été construit. Il peut s'agir d'un répertoire courant relatif.getAbsolutePath()
obtient la chaîne de chemin après l'avoir résolue dans le répertoire actuel, si elle est relative, ce qui donne un chemin complet.getCanonicalPath()
obtient la chaîne de chemin après la résolution de tout chemin relatif par rapport au répertoire en cours, et supprime tout chemin relatif (.
et ..
), ainsi que tout lien de système de fichiers pour renvoyer un chemin vers lequel le système de fichiers considère le moyen canonique de référencer l'objet du système de fichiers vers lequel il pointe.De plus, chacun de ceux-ci a un équivalent File qui retourne l'objet File
correspondant.
getPath()
renvoie le chemin utilisé pour créer l'objet File
. Cette valeur de retour n'est pas modifiée en fonction de l'emplacement où elle est exécutée (les résultats ci-dessous concernent les fenêtres, les séparateurs étant évidemment différents ailleurs).
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()
résoudra le chemin en fonction de l'emplacement d'exécution ou du lecteur. Donc, si exécuté depuis 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()
dépend du système. Cela résoudra l'emplacement unique que représente le chemin. Ainsi, si vous avez des "." Dans le chemin, ils seront généralement supprimés.
Quant à savoir quand les utiliser. Cela dépend de ce que vous essayez d'atteindre. getPath()
est utile pour la portabilité. getAbsolutePath()
est utile pour trouver l'emplacement du système de fichiers, et getCanonicalPath()
est particulièrement utile pour vérifier si deux fichiers sont identiques.
La chose importante à retenir est que la classe File
essaie de représenter ce que Sun appelle "des noms de chemin hiérarchiques" (essentiellement un chemin comme c:/foo.txt
ou /usr/muggins
). C'est pourquoi vous créez des fichiers en termes de chemins. Les opérations que vous décrivez sont toutes des opérations sur ce "chemin".
getPath()
récupère le chemin d'accès avec lequel le fichier a été créé (../foo.txt
)getAbsolutePath()
récupère le chemin avec lequel le fichier a été créé, mais inclut des informations sur le répertoire actuel si le chemin est relatif (/usr/bobstuff/../foo.txt
)getCanonicalPath()
tentatives pour extraire une représentation unique du chemin absolu du fichier. Ceci élimine l'indirection de ".." et "." références (/usr/foo.txt
).Note je dis tentatives - en formant un chemin canonique, le VM peut lancer un IOException
. Cela se produit généralement du fait qu’il effectue certaines opérations sur le système de fichiers, dont l’une peut échouer.
Je trouve que j’ai rarement besoin d’utiliser getCanonicalPath()
, mais si un fichier avec un nom de fichier au format DOS 8.3 sous Windows, tel que la propriété Java.io.tmpdir
System, est renvoyé, cette méthode " "nom de fichier complet".