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