Сравнение getPath (), getAbsolutePath () и getCanonicalPath () в Java
1. обзор
Классjava.io.File имеет три метода -getPath(),getAbsolutePath() иgetCanonicalPath() - для получения пути к файловой системе.
В этой статье мы кратко рассмотрим различия между ними и обсудим вариант использования, в котором вы можете выбрать одно вместо других.
2. Определения и примеры методов
Давайте начнем с определения трех методов вместе с примерами, основанными на наличии следующей структуры каталогов в домашнем каталоге пользователя:
|-- 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()с
Проще говоря,getPath() возвращает представлениеString абстрактного пути к файлу. По сути, этоthe pathname passed to the File constructor.
Итак, если объектFile был создан с использованием относительного пути, возвращаемое значение из методаgetPath() также будет относительным путем.
Если мы вызовем следующий код из каталога\{user.home}/example:
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 символ разделителя имен изменился с символа прямой косой черты (/), который был передан конструктору, на символ обратной косой черты (\). Это потому, чтоthe returned String always uses the platform’s default name-separator character.
2.2. getAbsolutePath()с
МетодgetAbsolutePath() возвращаетthe pathname of the file after resolving the path for the current user directory - это называется абсолютным путем. Итак, для нашего предыдущего примераfile.getAbsolutePath() вернет:
/home/username/example/foo/foo-one.txt // on Unix systems
C:\Users\username\example\foo\foo-one.txt // on Windows systems
Этот метод разрешает только текущий каталог для относительного пути. Сокращенные представления (такие как «.” и«..”) в дальнейшем не разрешаются. Следовательно, когда мы выполняем следующий код из каталога\{user.home}/example:
File file = new File("bar/baz/../bar-one.txt");
String path = file.getAbsolutePath();
Значение переменнойpath будет:
/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()с
МетодgetCanonicalPath() идет дальше иresolves the absolute pathname as well as the shorthands or redundant names like “.” and “..“ согласно структуре каталогов. Это такжеresolves symbolic links в системах Unix иconverts the drive letter to a standard case в системах Windows.
Итак, для предыдущего примера методgetCanonicalPath() вернет:
/home/username/example/bar/bar-one.txt // on Unix systems
C:\Users\username\example\bar\bar-one.txt // on Windows systems
Давайте возьмем другой пример. Учитывая текущий каталог как$\{user.home}/example и объектFile, созданный с использованием параметраnew File(“bar/baz/./baz-one.txt”), вывод дляgetCanonicalPath() будет:
/home/username/example/bar/baz/baz-one.txt // on Unix systems
C:\Users\username\example\bar\baz\baz-one.txt // on Windows Systems
Стоит упомянуть, что один файл в файловой системе может иметь бесконечное количество абсолютных путей, поскольку существует бесконечное количество способов использования сокращенных представлений. Однакоthe canonical path will always be unique, поскольку все такие представления разрешены.
В отличие от двух последних методов,getCanonicalPath() может выдатьIOException, потому что для этого требуются запросы файловой системы.
Например, в системах Windows, если мы создаем объектFile с одним из недопустимых символов, разрешение канонического пути выдастIOException:
new File("*").getCanonicalPath();
3. Случай использования
Допустим, мы пишем метод, который принимает объектFile в качестве параметра и сохраняет егоfully qualified name в базе данных. Мы не знаем, является ли путь относительным или содержит сокращения. В этом случае мы можем использоватьgetCanonicalPath().
Однако, посколькуgetCanonicalPath() читает файловую систему, это приводит к снижению производительности. Если мы уверены, что нет повторяющихся имен или символических ссылок, а регистр букв диска стандартизирован (при использовании ОС Windows), тогда мы должны предпочесть использоватьgetAbsoultePath().
4. Заключение
В этом кратком руководстве мы рассмотрели различия между тремя методамиFile для получения пути к файловой системе. Мы также показали случай использования, когда один метод может быть предпочтительнее другого.
Тестовый классJunit, демонстрирующий примеры из этой статьи, можно найтиover on GitHub.