N'oubliez pas Path.toAbsolutePath().normalize()qui est un bon compromis entre le chemin canonique (réel) et le chemin absolu seul.
eckes
Réponses:
625
Considérez ces noms de fichiers:
C:\temp\file.txt - Ceci est un chemin, un chemin absolu et un chemin canonique.
.\file.txt- Ceci 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 vers un chemin canonique le rend absolu (généralement clou sur le répertoire de travail actuel, par exemple, ./file.txtdevient 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 les liens symboliques (sous unix).
FWIW, ce n'est pas une donnée qui C:\temp\file.txtest un chemin canonique - le répertoire temporaire peut être un lien logiciel ou un lien dur de 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.
Lawrence Dol
1
path ne prend pas vraiment en compte ces problèmes ou l'existence de l'un des composants, seulement sa syntaxe.
escape-llc
Il le fait, le chemin canonique (contrairement au chemin normalisé) atteint le système de fichiers.
eckes
1
Fondamentalement, je ne vois pas pourquoi on devrait utiliser à la getAbsolutePath()place de getCanonicalPath(). Il semble même meilleur car le canon canon résout automatiquement ces ../parties.
Scadge
N'oubliez pas que getCanonicalPathjeter un IOExceptionmoment getAbsolutePathne fait pas, si c'est une considération.
Panier abandonné
129
La meilleure façon que j'ai trouvée pour avoir une idée de ce genre de choses est de les essayer:
import java.io.File;publicclassPathTesting{publicstaticvoid main(String[] args){File f =newFile("test/.././file.txt");System.out.println(f.getPath());System.out.println(f.getAbsolutePath());try{System.out.println(f.getCanonicalPath());}catch(Exception e){}}}
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. 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 Filespointent vers le même fichier sur le disque, vous pouvez comparer leurs chemins canoniques. Un seul exemple.
On peut soutenir que Java s'est trompé sur l'implémentation d'un chemin "absolu"; il aurait vraiment dû supprimer tous les éléments de chemin relatifs dans un chemin absolu. La forme canonique supprimerait alors tous les liens ou jonctions FS du chemin.
Lawrence Dol
but if you were trying to see if two Files are pointing at the same file on diskComment? exemple s'il vous plait?
Asif Mushtaq
@UnKnown: Vous utiliseriez le chemin canonique pour cela.
Lawrence Dol
67
En bref:
getPath()obtient la chaîne de chemin avec laquelle l' Fileobjet a été construit, et il peut s'agir du répertoire courant relatif.
getAbsolutePath() obtient 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 complet.
getCanonicalPath()obtient la chaîne de chemin d'accès après avoir résolu tout chemin relatif par rapport au répertoire en cours, et supprime tout cheminement relatif ( .et ..), et tous les liens du système de fichiers pour renvoyer 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.
En outre, chacun d'eux a un équivalent de fichier qui renvoie l' Fileobjet correspondant .
getPath()renvoie le chemin utilisé pour créer l' Fileobjet. 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 sont pour les fenêtres, les séparateurs sont évidemment différents ailleurs)
File f1 =newFile("/some/path");String path = f1.getPath();// will return "\some\path"File dir =newFile("/basedir");File f2 =newFile(dir,"/some/path");
path = f2.getPath();// will return "\basedir\some\path"File f3 =newFile("./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écutez à 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. Donc, 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 de réaliser. 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.
pouvez-vous m'en donner un exemple? getCanonicalPath() is particularly useful to check if two files are the same.
Asif Mushtaq
20
La grande chose à comprendre est que la Fileclasse essaie de représenter une vue de ce que Sun aime appeler des "chemins d'accès hiérarchiques" (essentiellement un chemin comme c:/foo.txtou /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 d'accès".
getPath()récupère le chemin avec lequel le fichier a été créé avec ( ../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()tente de récupérer une représentation unique du chemin absolu du fichier. Cela élimine l'indirection de ".." et "." références ( /usr/foo.txt).
Notez que je dis tentatives - en formant un chemin canonique, la VM peut lancer un IOException. Cela se produit généralement car il exécute certaines opérations du système de fichiers, dont l'une pourrait échouer.
Je trouve que j'ai rarement besoin d'utiliser getCanonicalPath()mais, si on me donne un fichier avec un nom de fichier au format DOS 8.3 sous Windows, tel que lejava.io.tmpdir retours de la propriété System, alors cette méthode retournera le nom de fichier "complet".
Path.toAbsolutePath().normalize()
qui est un bon compromis entre le chemin canonique (réel) et le chemin absolu seul.Réponses:
Considérez ces noms de fichiers:
C:\temp\file.txt
- Ceci est un chemin, un chemin absolu et un chemin canonique..\file.txt
- Ceci 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 vers un chemin canonique le rend absolu (généralement clou sur le répertoire de travail actuel, par exemple,
./file.txt
devientc:/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 les liens symboliques (sous unix).Notez également l'exemple suivant avec nio.Paths:
Bien que les deux chemins se réfèrent au même emplacement, la sortie sera assez différente:
la source
C:\temp\file.txt
est un chemin canonique - le répertoire temporaire peut être un lien logiciel ou un lien dur de 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.getAbsolutePath()
place degetCanonicalPath()
. Il semble même meilleur car le canon canon résout automatiquement ces../
parties.getCanonicalPath
jeter unIOException
momentgetAbsolutePath
ne fait pas, si c'est une considération.La meilleure façon que j'ai trouvée pour avoir une idée de ce genre de choses est de les essayer:
Votre sortie sera quelque chose comme:
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; etgetCanonicalPath()
vous donne le chemin absolu unique vers le 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 vers le même fichier sur le disque, vous pouvez comparer leurs chemins canoniques. Un seul exemple.la source
but if you were trying to see if two Files are pointing at the same file on disk
Comment? exemple s'il vous plait?En bref:
getPath()
obtient la chaîne de chemin avec laquelle l'File
objet a été construit, et il peut s'agir du répertoire courant relatif.getAbsolutePath()
obtient 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 complet.getCanonicalPath()
obtient la chaîne de chemin d'accès après avoir résolu tout chemin relatif par rapport au répertoire en cours, et supprime tout cheminement relatif (.
et..
), et tous les liens du système de fichiers pour renvoyer 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.En outre, chacun d'eux a un équivalent de fichier qui renvoie l'
File
objet correspondant .la source
getPath()
renvoie le chemin utilisé pour créer l'File
objet. 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 sont pour les fenêtres, les séparateurs sont évidemment différents ailleurs)getAbsolutePath()
résoudra le chemin en fonction de l'emplacement d'exécution ou du lecteur. Donc, si exécutez à partir dec:\test
:getCanonicalPath()
dépend du système. Il résoudra l'emplacement unique que le chemin représente. Donc, 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 de réaliser.
getPath()
est utile pour la portabilité.getAbsolutePath()
est utile pour trouver l'emplacement du système de fichiers etgetCanonicalPath()
est particulièrement utile pour vérifier si deux fichiers sont identiques.la source
getCanonicalPath() is particularly useful to check if two files are the same.
La grande chose à comprendre est que la
File
classe essaie de représenter une vue de ce que Sun aime appeler des "chemins d'accès hiérarchiques" (essentiellement un chemin commec:/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 d'accès".getPath()
récupère le chemin avec lequel le fichier a été créé avec (../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()
tente de récupérer une représentation unique du chemin absolu du fichier. Cela élimine l'indirection de ".." et "." références (/usr/foo.txt
).Notez que je dis tentatives - en formant un chemin canonique, la VM peut lancer un
IOException
. Cela se produit généralement car il exécute certaines opérations du système de fichiers, dont l'une pourrait échouer.la source
Je trouve que j'ai rarement besoin d'utiliser
getCanonicalPath()
mais, si on me donne un fichier avec un nom de fichier au format DOS 8.3 sous Windows, tel que lejava.io.tmpdir
retours de la propriété System, alors cette méthode retournera le nom de fichier "complet".la source