Сравнение getPath (), getAbsolutePath () и getCanonicalPath () в Java

Сравнение 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.