Quelle est la différence entre getPath()
, getAbsolutePath()
et getCanonicalPath()
en Java ?
Et quand dois-je utiliser chacun d'eux ?
Quelle est la différence entre getPath()
, getAbsolutePath()
et getCanonicalPath()
en Java ?
Et quand dois-je utiliser chacun d'eux ?
Considérez ces noms de fichiers :
C:\temp\file.txt
- Il s'agit d'un chemin, d'un chemin absolu et d'un chemin canonique.
.\file.txt
- Il s'agit d'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 d'accès en un chemin canonique le rend absolu (on ajoute généralement le répertoire de travail actuel, donc par exemple ./file.txt
devient c:/temp/file.txt
). Le chemin canonique d'un fichier ne fait que "purifier" le chemin, en supprimant et en résolvant des choses comme ..\
et la résolution des liens symboliques (sur les 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 réfèrent au même endroit, les résultats seront très différents :
C:\Windows
C:\Windows\System32\drivers
Pour info, il n'est pas acquis que C:\temp\file.txt
est un chemin canonique - le répertoire temp peut être un lien logiciel ou un lien matériel du système de fichiers (une jonction dans NTFS), et file.txt peut être un lien logiciel. Je ne sais pas si les systèmes de fichiers peuvent distinguer les liens durs vers les fichiers.
Le chemin ne tient pas vraiment compte de ces questions ni de l'existence de l'un ou l'autre des composants, mais uniquement de sa syntaxe.
C'est le cas, le chemin canonique (contrairement au chemin normalisé) touche le système de fichiers.
Le meilleur moyen que j'ai trouvé pour avoir une idée de ce genre de choses est de les 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 résultat 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 basé sur 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 vers le fichier. Remarquez qu'il existe un grand nombre de chemins absolus qui pointent vers le même fichier, mais un seul chemin canonique.
Quand utiliser chacun d'eux ? Cela dépend de ce que vous essayez d'accomplir, mais si vous essayez de voir si deux Files
pointent vers le même fichier sur le disque, vous pourriez comparer leurs chemins canoniques. Un seul exemple.
On peut soutenir que Java s'est trompé dans l'implémentation d'un chemin "absolu" ; il aurait vraiment dû supprimer tout élément de chemin relatif dans un chemin absolu. La forme canonique aurait alors supprimé tous les liens ou jonctions FS dans le chemin.
but if you were trying to see if two Files are pointing at the same file on disk
Comment ? Un exemple s'il vous plaît ?
En bref :
getPath()
récupère la chaîne de chemin que le File
avec lequel l'objet a été construit, et il peut s'agir du répertoire courant relatif.getAbsolutePath()
récupère la chaîne de chemin d'accès après l'avoir résolue par rapport au répertoire actuel si elle est relative, ce qui donne un chemin d'accès entièrement qualifié.getCanonicalPath()
récupère la chaîne du chemin après avoir résolu tout chemin relatif par rapport au répertoire actuel, et supprime tout chemin relatif ( .
et ..
), et tous les liens du système de fichiers pour retourner un chemin que le système de fichiers considère comme le moyen canonique de référencer l'objet du système de fichiers vers lequel il pointe.De plus, chacun de ces éléments a un équivalent de type File qui renvoie le fichier correspondant. File
objet.
Notez que, selon l'OMI, Java s'est trompé dans l'implémentation d'un chemin "absolu" ; il devrait vraiment supprimer tout élément de chemin relatif dans un chemin absolu. La forme canonique supprimerait alors tous les liens ou jonctions FS dans le chemin.
getPath()
renvoie le chemin utilisé pour créer le File
objet. Cette valeur de retour n'est pas modifiée en fonction de l'endroit où elle est exécutée (les résultats ci-dessous sont pour Windows, les séparateurs sont é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. Ainsi, si l'exécution se fait à partir de 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. Il résoudra l'emplacement unique que le chemin représente. 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'obtenir. 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 la plus importante à comprendre, c'est que le File
tente de représenter une vue de ce que Sun aime appeler les "noms de chemin hiérarchiques" (en gros, 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 "nom de chemin".
getPath()
récupère le chemin 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 récupérer une représentation unique du chemin absolu du fichier. Cela élimine l'indirection des références ".." et "." ( /usr/foo.txt
).Notez que je dis tentatives - dans la formation d'un chemin canonique, la VM peut lancer un IOException
. Cela se produit généralement parce qu'il effectue certaines opérations sur le système de fichiers, dont chacune peut échouer.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
1 votes
N'oubliez pas
Path.toAbsolutePath().normalize()
qui est un bon compromis entre le chemin canonique (réel) et le chemin absolu seul.