Saltar al contenido

Diferencia entre getCanonicalPath y toRealPath

Al fin luego de tanto luchar hemos hallado la contestación de este atascamiento que agunos usuarios de este sitio tienen. Si deseas aportar alguna información no dejes de aportar tu comentario.

Solución:

Conclusiones:

  • getAbsolutePath y getPath nunca fallar, ya que no hacen validación
  • getCanonicalPath llegar a resultados no válidos cuando la letra de unidad de la URL no es válida o es diferente a la carpeta actual
  • toPath().toRealPath() está comprobando la validez, pero el archivo debe existir y también puede seguir o no seguir enlaces simbólicos
  • toPath() es lo suficientemente seguro y no necesita que el archivo exista.
  • .toPath().toAbsolutePath().normalize() es el mejor sin la necesidad de que exista un archivo

Hice una prueba similar de @John en Windows

  @Test
  public void testCanonical() throws IOException )");
    test("d:tarGetu0000Suffix", "Path contains invalid chars in both linux and windows (\0)");
  

  private void test(String filename, String message) throws IOException 
    java.io.File file = new java.io.File(filename);
    System.out.println("Use:  " + filename + " -> " + message);
    System.out.println("F-GET:     " + Try.of(() -> file.getPath()));
    System.out.println("F-ABS:     " + Try.of(() -> file.getAbsolutePath()));
    System.out.println("F-CAN:     " + Try.of(() -> file.getCanonicalPath()));
    System.out.println("P-TO:      " + Try.of(() -> file.toPath()));
    System.out.println("P-ABS:     " + Try.of(() -> file.toPath().toAbsolutePath()));
    System.out.println("P-NOR:     " + Try.of(() -> file.toPath().normalize()));
    System.out.println("P-NOR-ABS: " + Try.of(() -> file.toPath().normalize().toAbsolutePath()));
    System.out.println("P-ABS-NOR: " + Try.of(() -> file.toPath().toAbsolutePath().normalize()));
    System.out.println("P-REAL:    " + Try.of(() -> file.toPath().toRealPath()));
    System.out.println("");
  

Los resultados son:

Use:  d:tarGet..Target -> File exist and drive letter is on the current one
F-GET:     Success(d:tarGet..Target)
F-ABS:     Success(d:homeraiserworkrestfstarGet..Target)
F-CAN:     Success(D:homeraiserworkrestfstarget)
P-TO:      Success(d:tarGet..Target)
P-ABS:     Success(D:homeraiserworkrestfstarGet..Target)
P-NOR:     Success(d:Target)
P-NOR-ABS: Success(D:homeraiserworkrestfsTarget)
P-ABS-NOR: Success(D:homeraiserworkrestfsTarget)
P-REAL:    Success(D:homeraiserworkrestfstarget)

Use:  d:tarGet..Target... -> File exist and drive letter is on the current one, but parent of current drive should exist
F-GET:     Success(d:tarGet..Target...)
F-ABS:     Success(d:homeraiserworkrestfstarGet..Target...)
F-CAN:     Success(D:homeraiserworkrestfs)
P-TO:      Success(d:tarGet..Target...)
P-ABS:     Success(D:homeraiserworkrestfstarGet..Target...)
P-NOR:     Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL:    Success(D:homeraiserworkrestfs)

Use:  d:tarGetnon-existent....Target... -> Relative path contains non-existent file
F-GET:     Success(d:tarGetnon-existent....Target...)
F-ABS:     Success(d:homeraiserworkrestfstarGetnon-existent....Target...)
F-CAN:     Success(D:homeraiserworkrestfs)
P-TO:      Success(d:tarGetnon-existent....Target...)
P-ABS:     Success(D:homeraiserworkrestfstarGetnon-existent....Target...)
P-NOR:     Success(d:)
P-NOR-ABS: Success(D:homeraiserworkrestfs)
P-ABS-NOR: Success(D:homeraiserworkrestfs)
P-REAL:    Success(D:homeraiserworkrestfs)

Use:  d:target\file -> Double slash
F-GET:     Success(d:targetfile)
F-ABS:     Success(d:homeraiserworkrestfstargetfile)
F-CAN:     Success(D:homeraiserworkrestfstargetfile)
P-TO:      Success(d:targetfile)
P-ABS:     Success(D:homeraiserworkrestfstargetfile)
P-NOR:     Success(d:targetfile)
P-NOR-ABS: Success(D:homeraiserworkrestfstargetfile)
P-ABS-NOR: Success(D:homeraiserworkrestfstargetfile)
P-REAL:    Failure(java.nio.file.NoSuchFileException: D:homeraiserworkrestfstargetfile)

Use:  c:tarGet..Target. -> File doesn't exist and drive letter is on different drive than the current one
F-GET:     Success(c:tarGet..Target.)
F-ABS:     Success(c:\tarGet..Target.)
F-CAN:     Success(C:Target)
P-TO:      Success(c:tarGet..Target.)
P-ABS:     Success(C:tarGet..Target.)
P-NOR:     Success(c:Target)
P-NOR-ABS: Success(C:Target)
P-ABS-NOR: Success(C:Target)
P-REAL:    Failure(java.nio.file.NoSuchFileException: C:Target)

Use:  l:tarGet..Target... -> Drive letter doesn't exist
F-GET:     Success(l:tarGet..Target...)
F-ABS:     Success(l:tarGet..Target...)
F-CAN:     Success(L:)
P-TO:      Success(l:tarGet..Target...)
P-ABS:     Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-NOR:     Success(l:)
P-NOR-ABS: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-ABS-NOR: Failure(java.io.IOError: java.io.IOException: Unable to get working directory of drive 'L')
P-REAL:    Failure(java.io.IOException: Unable to get working directory of drive 'L')

Use:  za:tarGet..Target... -> Drive letter is double so not valid
F-GET:     Success(za:tarGet..Target...)
F-ABS:     Success(D:homeraiserworkrestfsza:tarGet..Target...)
F-CAN:     Success(D:homeraiserworkrestfs)
P-TO:      Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS:     Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR:     Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)
P-REAL:    Failure(java.nio.file.InvalidPathException: Illegal char <:> at index 2: za:tarGet..Target...)

Use:  d:tarGet|Suffix -> Path contains invalid chars in windows (|)
F-GET:     Success(d:tarGet|Suffix)
F-ABS:     Success(d:homeraiserworkrestfstarGet|Suffix)
F-CAN:     Failure(java.io.IOException: The filename, directory name, or volume label syntax is incorrect)
P-TO:      Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS:     Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR:     Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-NOR-ABS: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-ABS-NOR: Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)
P-REAL:    Failure(java.nio.file.InvalidPathException: Illegal char <|> at index 8: d:tarGet|Suffix)

Una ruta canónica es absoluta y única, pero tendrá un significado diferente en diferentes sistemas.

Un nombre de ruta canónico es absoluto y único. La definición precisa de forma canónica depende del sistema.

Un camino real es el real camino con respecto al sistema. También tendría que pasar si no se ocupa o no de los enlaces simbólicos, donde se maneja implícitamente con canonicalPath.

La definición precisa de este método depende de la implementación, pero en general se deriva de esta ruta, una ruta absoluta que ubica el mismo archivo que esta ruta, pero con elementos de nombre que representan el nombre real de los directorios y el archivo. Por ejemplo, donde las comparaciones de nombres de archivos en un sistema de archivos no distinguen entre mayúsculas y minúsculas luego los elementos del nombre representan los nombres en su caso real. Además, la ruta resultante tiene elementos de nombre redundantes eliminados.

Entonces, sí, estos dos métodos pueden devolver cosas diferentes, pero realmente depende de su sistema. Si necesita algo que sea único, entonces canonicalPath es tu apuesta más segura, incluso si no es una Path.

Lo que noté de mis pruebas es que

  • Path.toRealPath () lanzará java.nio.file.NoSuchFileException si el archivo no existe (Javadoc: Devuelve el verdadero camino de un existente expediente.)

  • File.getCanonicalPath () no generará una excepción si el archivo no existe (solo generará IOException si el nombre del archivo no es válido y contiene un carácter ‘ 0’).

Por lo tanto, el primero no sería adecuado si desea usarlo para verificaciones de ruta antes de crear el archivo.

Tiene razón en que el Javadoc para ambos métodos es algo superficial.

Sección de Reseñas y Valoraciones

Si para ti ha resultado provechoso este post, sería de mucha ayuda si lo compartes con más programadores y nos ayudes a extender nuestro contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *