Respuestas:
Considere estos nombres de archivo:
C:\temp\file.txt
- Este es un camino, un camino absoluto y un camino canónico.
.\file.txt
- Este es un camino. No es un camino absoluto ni un camino canónico.
C:\temp\myapp\bin\..\\..\file.txt
- Este es un camino y un camino absoluto. No es un camino canónico.
Un camino canónico es siempre un camino absoluto.
La conversión de una ruta a una ruta canónica lo hace absoluto (generalmente se agrega al directorio de trabajo actual, por ejemplo, se ./file.txt
convierte en c:/temp/file.txt
). La ruta canónica de un archivo simplemente "purifica" la ruta, eliminando y resolviendo cosas como ..\
y resolviendo enlaces simbólicos (en unixes).
También tenga en cuenta el siguiente ejemplo 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());
Si bien ambas rutas se refieren a la misma ubicación, la salida será bastante diferente:
C:\Windows
C:\Windows\System32\drivers
C:\temp\file.txt
sea una ruta canónica: el directorio temporal puede ser un enlace suave o un enlace duro del sistema de archivos (una unión en NTFS), y file.txt podría ser un enlace suave. No sé si los sistemas de archivos pueden distinguir los enlaces duros a los archivos.
getAbsolutePath()
lugar de getCanonicalPath()
. Incluso se ve mejor porque el canónico resuelve automáticamente esas ../
partes.
getCanonicalPath
tira un IOException
rato getAbsolutePath
no, si esto es una consideración.
La mejor manera que he encontrado para tener una idea de cosas como esta es probarlas:
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) {}
}
}
Su salida será algo así como:
test\..\.\file.txt
C:\projects\sandbox\trunk\test\..\.\file.txt
C:\projects\sandbox\trunk\file.txt
Por lo tanto, getPath()
le proporciona la ruta basada en el objeto Archivo, que puede ser relativa o no; getAbsolutePath()
le da una ruta absoluta al archivo; y getCanonicalPath()
le da la ruta absoluta única al archivo. Tenga en cuenta que hay una gran cantidad de rutas absolutas que apuntan al mismo archivo, pero solo una ruta canónica.
¿Cuándo usar cada uno? Depende de lo que intente lograr, pero si intentara ver si dos Files
apuntan al mismo archivo en el disco, podría comparar sus rutas canónicas. Solo un ejemplo.
but if you were trying to see if two Files are pointing at the same file on disk
¿Cómo? ejemplo por favor?
En breve:
getPath()
obtiene la cadena de ruta con la que File
se construyó el objeto, y puede ser un directorio actual relativo.getAbsolutePath()
obtiene la cadena de ruta después de resolverla en el directorio actual si es relativa, lo que resulta en una ruta totalmente calificada.getCanonicalPath()
obtiene la cadena de ruta después de resolver cualquier ruta relativa contra el directorio actual, y elimina cualquier ruta relativa ( .
y ..
), y cualquier enlace del sistema de archivos para devolver una ruta que el sistema de archivos considera el medio canónico para hacer referencia al objeto del sistema de archivos al que apunta.Además, cada uno de estos tiene un archivo equivalente que devuelve el File
objeto correspondiente .
getPath()
devuelve la ruta utilizada para crear el File
objeto. Este valor de retorno no cambia en función de la ubicación en la que se ejecuta (los resultados a continuación son para ventanas, los separadores son obviamente diferentes en otros lugares)
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()
resolverá la ruta en función de la ubicación o unidad de ejecución. Entonces, si se ejecuta desde 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()
depende del sistema Resolverá la ubicación única que representa la ruta. Entonces, si tiene algún "." En la ruta, generalmente se eliminarán.
En cuanto a cuándo usarlos. Depende de lo que intentes lograr. getPath()
Es útil para la portabilidad. getAbsolutePath()
es útil para encontrar la ubicación del sistema de archivos y getCanonicalPath()
es particularmente útil para verificar si dos archivos son iguales.
getCanonicalPath() is particularly useful to check if two files are the same.
Lo importante para entender es que la File
clase trata de representar una vista de lo que a Sun le gusta llamar "rutas jerárquicas" (básicamente, una ruta como c:/foo.txt
o /usr/muggins
). Es por eso que crea archivos en términos de rutas. Las operaciones que está describiendo son todas operaciones sobre este "nombre de ruta".
getPath()
recupera la ruta con la que se creó el archivo ( ../foo.txt
)getAbsolutePath()
recupera la ruta con la que se creó el archivo, pero incluye información sobre el directorio actual si la ruta es relativa ( /usr/bobstuff/../foo.txt
)getCanonicalPath()
intenta obtener una representación única de la ruta absoluta al archivo. Esto elimina la indirección de ".." y "." referencias ( /usr/foo.txt
).Tenga en cuenta que digo intentos : al formar una ruta canónica, la VM puede lanzar un IOException
. Esto generalmente ocurre porque está realizando algunas operaciones del sistema de archivos, cualquiera de las cuales podría fallar.
Creo que rara vez necesito usarlo getCanonicalPath()
, pero si se le da un archivo con un nombre de archivo que está en formato DOS 8.3 en Windows, como la java.io.tmpdir
propiedad del sistema, entonces este método devolverá el nombre de archivo "completo".
Path.toAbsolutePath().normalize()
cuál es un buen término medio entre la ruta canónica (real) y la ruta absoluta solo.