1. Обзор
В java.io.Класс File имеет три метода — getPath() , getAbsolutePath() и getCanonicalPath() — для получения пути к файловой системе.
В этой статье мы быстро рассмотрим различия между ними и обсудим вариант использования, в котором вы можете выбрать один из них вместо других.
2. Определения и примеры методов
Давайте начнем с рассмотрения определений трех методов, а также примеров, основанных на наличии следующей структуры каталогов в домашнем каталоге пользователя:
|-- 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()
Проще говоря, getPath() возвращает Строку представление абстрактного пути к файлу. По сути, это путь, переданный в Файл конструктор .
Таким образом, если объект File был создан с использованием относительного пути, возвращаемое значение из метода getPath() также будет относительным путем.
Если мы вызовем следующий код из каталога {user.home}/baeldung :
File file = new File("foo/foo-one.txt"); String path = file.getPath();
Переменная path будет иметь значение:
foo/foo-one.txt // on Unix systems foo\foo-one.txt // on Windows systems
Обратите внимание, что в системе Windows символ разделителя имен изменился с символа прямой косой черты (/), который был передан конструктору, на символ обратной косой черты ( \ ). Это связано с тем, что возвращаемая Строка всегда использует символ разделителя имени платформы по умолчанию .
2.2. getAbsolutePath()
Метод getAbsolutePath() возвращает путь к файлу после разрешения пути для текущего каталога пользователя — это называется абсолютным путем. Итак, в нашем предыдущем примере file.getAbsolutePath() вернет:
/home/username/baeldung/foo/foo-one.txt // on Unix systems C:\Users\username\baeldung\foo\foo-one.txt // on Windows systems
Этот метод разрешает только текущий каталог для относительного пути. Стенографические представления (такие как ” .” и ” ..” ) далее не разрешаются. Следовательно, когда мы выполняем следующий код из каталога {user.home}/baeldung:
File file = new File("bar/baz/../bar-one.txt"); String path = file.getAbsolutePath();
Значение переменной path будет равно:
/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()
Метод getCanonicalPath() идет дальше и разрешает абсолютный путь, а также сокращенные или избыточные имена, такие как “ . ” и “ .. “ в соответствии со структурой каталогов. Он также разрешает символические ссылки в системах Unix и преобразует букву диска в стандартный регистр в системах Windows.
Таким образом, в предыдущем примере метод getCanonicalPath() вернет:
/home/username/baeldung/bar/bar-one.txt // on Unix systems C:\Users\username\baeldung\bar\bar-one.txt // on Windows systems
Давайте возьмем другой пример. Заданный текущий каталог как ${user.home}/baeldung и Файл объект, созданный с помощью параметра новый файл(“bar/baz/./baz-one.txt”) , вывод для getCanonicalPath() будет:
/home/username/baeldung/bar/baz/baz-one.txt // on Unix systems C:\Users\username\baeldung\bar\baz\baz-one.txt // on Windows Systems
Стоит отметить, что один файл в файловой системе может иметь бесконечное количество абсолютных путей, поскольку существует бесконечное количество способов использования сокращенных представлений. Однако канонический путь всегда будет уникальным , поскольку все такие представления разрешены.
В отличие от последних двух методов, getCanonicalPath() может вызвать IOException потому что для этого требуются запросы файловой системы.
Например, в системах Windows, если мы создадим объект File с одним из запрещенных символов, разрешение канонического пути вызовет исключение IOException :
new File("*").getCanonicalPath();
3. Пример использования
Допустим, мы пишем метод, который принимает объект File в качестве параметра и сохраняет его полное имя в базу данных. Мы не знаем, является ли путь относительным или содержит сокращения. В этом случае мы можем использовать getCanonicalPath() .
Однако, поскольку getCanonicalPath() считывает файловую систему, это связано с затратами на производительность. Если мы уверены, что нет избыточных имен или символических ссылок, а регистр букв диска стандартизирован (при использовании ОС Windows), то мы должны предпочесть использовать getAbsoultePath() .
4. Заключение
В этом кратком руководстве мы рассмотрели различия между тремя методами File для получения пути к файловой системе. Мы также показали пример использования, когда один метод может быть предпочтительнее другого.
Тестовый класс Junit , демонстрирующий примеры этой статьи, можно найти на GitHub .