Comparando getPath (), getAbsolutePath () e getCanonicalPath () em Java

Comparando getPath (), getAbsolutePath () e getCanonicalPath () em Java

1. Visão geral

A classejava.io.File tem três métodos -getPath(),getAbsolutePath()egetCanonicalPath() - para obter o caminho do sistema de arquivos.

Neste artigo, daremos uma olhada rápida nas diferenças entre eles e discutiremos um caso de uso em que você pode escolher usar um em vez dos outros.

2. Definições e exemplos de métodos

Vamos começar revisando as definições dos três métodos, juntamente com exemplos baseados em ter a seguinte estrutura de diretório presente no diretório inicial do usuário:

|-- example
    |-- example.txt
    |-- foo
    |   |-- foo-one.txt
    |   \-- foo-two.txt
    \-- bar
        |-- bar-one.txt
        |-- bar-two.txt
        \-- baz
            |-- baz-one.txt
            \-- baz-two.txt

2.1. getPath()

Simplificando,getPath() retorna a representaçãoString do nome do caminho abstrato do arquivo. Isso é essencialmentethe pathname passed to the File constructor.

Portanto, se o objetoFile foi criado usando um caminho relativo, o valor retornado do métodogetPath() também seria um caminho relativo.

Se invocarmos o seguinte código do diretório\{user.home}/example:

File file = new File("foo/foo-one.txt");
String path = file.getPath();

A variávelpath teria o valor:

foo/foo-one.txt  // on Unix systems
foo\foo-one.txt  // on Windows systems

Observe que, para o sistema Windows, o caractere separador de nome foi alterado do caractere de barra (/), passado para o construtor, para o caractere de barra invertida (\). Isso ocorre porquethe returned String always uses the platform’s default name-separator character.

2.2. getAbsolutePath()

O métodogetAbsolutePath() retornathe pathname of the file after resolving the path for the current user directory - isso é chamado de nome de caminho absoluto. Portanto, para nosso exemplo anterior,file.getAbsolutePath() retornaria:

/home/username/example/foo/foo-one.txt     // on Unix systems
C:\Users\username\example\foo\foo-one.txt  // on Windows systems

Este método resolve apenas o diretório atual para um caminho relativo. As representações abreviadas (como “.”e“..”) não são resolvidas posteriormente. Portanto, quando executamos o seguinte código do diretório\{user.home}/example:

File file = new File("bar/baz/../bar-one.txt");
String path = file.getAbsolutePath();

O valor da variávelpath seria:

/home/username/example/bar/baz/../bar-one.txt      // on Unix systems
C:\Users\username\example\bar\baz\..\bar-one.txt   // on Windows systems

2.3. getCanonicalPath()

O métodogetCanonicalPath() vai um passo adiante eresolves the absolute pathname as well as the shorthands or redundant names like “.” and “.. de acordo com a estrutura do diretório. Tambémresolves symbolic links em sistemas Unix econverts the drive letter to a standard case em sistemas Windows.

Portanto, para o exemplo anterior, o métodogetCanonicalPath() retornaria:

/home/username/example/bar/bar-one.txt     // on Unix systems
C:\Users\username\example\bar\bar-one.txt  // on Windows systems

Vamos dar outro exemplo. Dado o diretório atual como$\{user.home}/exampleeFile objeto criado usando o parâmetronew File(“bar/baz/./baz-one.txt”), a saída paragetCanonicalPath() seria:

/home/username/example/bar/baz/baz-one.txt     // on Unix systems
C:\Users\username\example\bar\baz\baz-one.txt  // on Windows Systems

Vale a pena mencionar que um único arquivo no sistema de arquivos pode ter um número infinito de caminhos absolutos, pois há um número infinito de maneiras pelas quais as representações taquigráficas podem ser usadas. No entanto,the canonical path will always be unique, pois todas essas representações foram resolvidas.

Ao contrário dos dois últimos métodos,getCanonicalPath() pode lançarIOException porque requer consultas ao sistema de arquivos.

Por exemplo, em sistemas Windows, se criarmos um objetoFile com um dos caracteres ilegais, resolver o caminho canônico lançará umIOException:

new File("*").getCanonicalPath();

3. Caso de Uso

Digamos que estejamos escrevendo um método que leva um objetoFile como um parâmetro e salva seufully qualified name em um banco de dados. Não sabemos se o caminho é relativo ou contém atalhos. Nesse caso, podemos querer usargetCanonicalPath().

No entanto, comogetCanonicalPath() lê o sistema de arquivos, isso tem um custo de desempenho. Se tivermos certeza de que não há nomes redundantes ou links simbólicos e a caixa das letras de unidade for padronizada (se estiver usando um sistema operacional Windows), devemos preferir usargetAbsoultePath().

4. Conclusão

Neste tutorial rápido, cobrimos as diferenças entre os três métodosFile para obter o caminho do sistema de arquivos. Também mostramos um caso de uso em que um método pode ser preferido em relação ao outro.

Uma classe de testeJunit demonstrando os exemplos deste artigo pode ser encontradaover on GitHub.