Какая разница между getPath(), getAbsolutePath() и getCanonicalPath() в Java? - программирование
Подтвердить что ты не робот

Какая разница между getPath(), getAbsolutePath() и getCanonicalPath() в Java?

В чем разница между getPath(), getAbsolutePath() и getCanonicalPath() в Java?

И когда я использую каждый из них?

4b9b3361

Ответ 1

Рассмотрим эти имена файлов:

C:\temp\file.txt - Это путь, абсолютный путь и канонический путь.

.\file.txt - Это путь. Это ни абсолютный путь, ни канонический путь.

C:\temp\myapp\bin\..\\..\file.txt - Это путь и абсолютный путь. Это не канонический путь.

Канонический путь всегда является абсолютным путем.

Преобразование из пути в канонический путь делает его абсолютным (обычно привязка к текущему рабочему каталогу, например, ./file.txt становится c:/temp/file.txt). Канонический путь файла просто "очищает" путь, удаляет и разрешает такие вещи, как ..\ и разрешает символические ссылки (в unixes).

Также обратите внимание на следующий пример с 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());

Хотя оба пути относятся к одному и тому же местоположению, вывод будет совсем другим:

C:\Windows
C:\Windows\System32\drivers

Ответ 2

Лучший способ, который я нашел, чтобы почувствовать такие вещи, это попробовать:

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) {}
    }
}

Ваш результат будет примерно таким:

test\..\.\file.txt
C:\projects\sandbox\trunk\test\..\.\file.txt
C:\projects\sandbox\trunk\file.txt

Итак, getPath() предоставляет вам путь, основанный на объекте File, который может быть или не быть относительным; getAbsolutePath() дает вам абсолютный путь к файлу; и getCanonicalPath() дает вам уникальный абсолютный путь к файлу. Обратите внимание, что существует огромное количество абсолютных путей, указывающих на один и тот же файл, но только на один канонический путь.

Когда использовать каждый? В зависимости от того, что вы пытаетесь выполнить, но если вы пытаетесь увидеть, указывают ли два Files на один и тот же файл на диске, вы можете сравнить их канонические пути. Только один пример.

Ответ 3

Короче:

  • getPath() получает строку пути, с которой был создан объект File, и может быть относительным текущим каталогом.
  • getAbsolutePath() получает строку пути после ее разрешения против текущего каталога, если он относительный, что приводит к полностью квалифицированному пути.
  • getCanonicalPath() получает строку пути после разрешения любого относительного пути к текущему каталогу и удаляет любые относительные пути (. и ..), а любые ссылки файловой системы возвращают путь, который файловая система считает каноническим означает ссылку на объект файловой системы, на который он указывает.

Кроме того, каждый из них имеет эквивалент файла, который возвращает соответствующий объект File.

Ответ 4

getPath() возвращает путь, используемый для создания объекта File. Это возвращаемое значение не изменяется в зависимости от местоположения, которое оно выполняется (результаты ниже для окон, разделители, очевидно, отличаются друг от друга)

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() разрешит путь, основанный на месте выполнения или диске. Поэтому, если вы используете 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() зависит от системы. Он разрешит уникальное местоположение, которое представляет путь. Поэтому, если у вас есть какие-либо "." S на пути, они обычно будут удалены.

О том, когда их использовать. Это зависит от того, чего вы пытаетесь достичь. getPath() полезен для переносимости. getAbsolutePath() полезно найти местоположение файловой системы, а getCanonicalPath() особенно полезно проверить, совпадают ли два файла.

Ответ 5

Самое главное, чтобы ваша голова была в том, что класс File пытается представить представление о том, что Sun любит называть "иерархические пути" (в основном путь типа "c:/foo.txt" или /usr/muggins ").Поэтому вы создаете файлы в терминах путей. Операции, которые вы описываете, - это все операции над этим" именем пути ".

  • getPath() выбирает путь, с которым был создан файл (../foo.txt)
  • getAbsolutePath() выбирает путь, с которым был создан Файл, но содержит информацию о текущем каталоге, если путь относительный (/usr/bobstuff/../foo.txt)
  • getCanonicalPath() попытки получить уникальное представление абсолютного пути к файлу. Это устраняет косвенность от ".." и ".". ссылки (/usr/foo.txt).

Примечание. Я говорю попытки - при формировании Канонического Пути, VM может выбросить IOException. Обычно это происходит из-за того, что он выполняет некоторые операции с файловой системой, любой из которых может выйти из строя.

Ответ 6

Я считаю, что мне редко приходится использовать getCanonicalPath(), но если задан файл с именем файла, который находится в формате DOS 8.3 в Windows, например, свойство java.io.tmpdir System возвращает, то этот метод вернет "полный" filename.