Confronto di getPath (), getAbsolutePath () e getCanonicalPath () in Java

1. Panoramica

La classe java.io.File ha tre metodi - getPath () , getAbsolutePath () e getCanonicalPath () - per ottenere il percorso del file system.

In questo articolo, daremo una rapida occhiata alle differenze tra di loro e discuteremo un caso d'uso in cui puoi scegliere di usarne uno rispetto agli altri.

2. Definizioni ed esempi di metodi

Iniziamo esaminando le definizioni dei tre metodi, insieme agli esempi basati sull'avere la seguente struttura di directory presente nella directory home dell'utente:

|-- baeldung |-- baeldung.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 ()

In poche parole, getPath () restituisce la rappresentazione String del percorso astratto del file. Questo è essenzialmente il percorso passato al costruttore di file .

Quindi, se l' oggetto File è stato creato utilizzando un percorso relativo, anche il valore restituito dal metodo getPath () sarebbe un percorso relativo.

Se invochiamo il seguente codice dalla directory {user.home} / baeldung :

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

La variabile del percorso avrebbe il valore:

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

Si noti che per il sistema Windows, il carattere separatore del nome è cambiato dal carattere barra (/), passato al costruttore, al carattere barra rovesciata (\). Questo perché la stringa restituita utilizza sempre il carattere separatore del nome predefinito della piattaforma .

2.2. getAbsolutePath ()

Il metodo getAbsolutePath () restituisce il percorso del file dopo aver risolto il percorso per la directory utente corrente - questo è chiamato percorso assoluto. Quindi, per il nostro esempio precedente, file.getAbsolutePath () restituirà:

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

Questo metodo risolve solo la directory corrente per un percorso relativo. Le rappresentazioni stenografiche (come " ." E " .." ) non vengono risolte ulteriormente. Quindi quando eseguiamo il seguente codice dalla directory {user.home} / baeldung:

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

Il valore della variabile path sarebbe:

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

2.3. getCanonicalPath ()

Il metodo getCanonicalPath () fa un ulteriore passo avanti e risolve il nome del percorso assoluto, nonché i nomi abbreviati o ridondanti come " . "E" .. " secondo la struttura della directory. Risolve anche i collegamenti simbolici sui sistemi Unix e converte la lettera di unità in un caso standard sui sistemi Windows.

Quindi, per l'esempio precedente, il metodo getCanonicalPath () restituirà:

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

Facciamo un altro esempio. Data la directory corrente come $ {user.home} / baeldung e l' oggetto File creato utilizzando il parametro new File ("bar / baz /./ baz-one.txt") , l'output per getCanonicalPath () sarebbe:

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

Vale la pena ricordare che un singolo file sul filesystem può avere un numero infinito di percorsi assoluti poiché esiste un numero infinito di modi in cui le rappresentazioni stenografiche possono essere utilizzate. Tuttavia, il percorso canonico sarà sempre unico poiché tutte queste rappresentazioni vengono risolte.

A differenza degli ultimi due metodi, getCanonicalPath () può generare IOException perché richiede query sul file system.

Ad esempio, su sistemi Windows, se creiamo un oggetto File con uno dei caratteri illegali, la risoluzione del percorso canonico genererà un'eccezione IOException :

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

3. Caso d'uso

Diciamo che stiamo scrivendo un metodo che accetta un oggetto File come parametro e salva il suo nome completo in un database. Non sappiamo se il percorso è relativo o contiene abbreviazioni. In questo caso, potremmo voler utilizzare getCanonicalPath () .

Tuttavia, poiché getCanonicalPath () legge il filesystem, ha un costo in termini di prestazioni. Se siamo sicuri che non ci sono nomi ridondanti o collegamenti simbolici e le lettere maiuscole e minuscole sono standardizzate (se si utilizza un sistema operativo Windows), allora dovremmo preferire usare getAbsoultePath () .

4. Conclusione

In questo breve tutorial, abbiamo coperto le differenze tra i tre metodi File per ottenere il percorso del file system. Abbiamo anche mostrato un caso d'uso in cui un metodo può essere preferito rispetto all'altro.

Una lezione di prova Junit che mostra gli esempi di questo articolo può essere trovata su GitHub.