6

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

1

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

Когда следует использовать каждый из них?

5 ответ(ов)

6

Вопрос: Каковы отличия между абсолютными, каноническими и относительными путями в Java, особенно в контексте использования nio.Paths?

Ответ: Давайте рассмотрим приведенные примеры файловых путей:

  1. C:\temp\file.txt - Это абсолютный путь и канонический путь.
  2. .\file.txt - Это путь, однако он не является ни абсолютным, ни каноническим.
  3. C:\temp\myapp\bin\..\\..\file.txt - Это абсолютный путь, но не канонический.

Канонический путь всегда является абсолютным. Преобразование относительного или неканонического пути в канонический путь делает его абсолютным. Обычно это делается путем добавления текущего рабочего каталога, таким образом ./file.txt становится C:/temp/file.txt. Канонический путь "очищает" путь, удаляя и разрешая такие элементы, как ..\, а также разрешая символические ссылки (на Unix-подобных системах).

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

Таким образом, при работе с путями в Java важно учитывать, как различные типы путей могут влиять на результат, особенно при использовании методов для получения родительского каталога.

1

Лучший способ понять, как работают разные методы для работы с путями файлов, — это попробовать их на практике. Вот пример кода на Java:

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) {
            e.printStackTrace();
        }
    }
}

Результат выполнения программы будет что-то вроде:

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

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

Когда использовать каждый из них? Это зависит от вашей задачи. Например, если вы хотите узнать, указывают ли два объекта File на один и тот же файл на диске, вы можете сравнить их канонические пути. Это всего лишь один из примеров использования.

0

В кратце:

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

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

Обратите внимание, что, по моему мнению, в Java неправильно реализована концепция "абсолютного" пути; на самом деле, в абсолютном пути следовало бы удалять любые относительные элементы. Каноническая форма, в свою очередь, удаляла бы любые файловые системные ссылки или джунки в пути.

0

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

File f1 = new File("/some/path");
String path = f1.getPath(); // вернет "\some\path"

File dir = new File("/basedir");
File f2 = new File(dir, "/some/path");
path = f2.getPath(); // вернет "\basedir\some\path"

File f3 = new File("./some/path");
path = f3.getPath(); // вернет ".\some\path"

Метод getAbsolutePath() разрешает путь на основе текущего местоположения или диска. Например, если программа запущена из c:\test:

path = f1.getAbsolutePath(); // вернет "c:\some\path"
path = f2.getAbsolutePath(); // вернет "c:\basedir\some\path"
path = f3.getAbsolutePath(); // вернет "c:\test\.\basedir\some\path"

Метод getCanonicalPath() зависит от операционной системы. Он разрешает уникальное положение, которое представляет собой путь. Таким образом, если в пути есть символы ".", они обычно будут удалены.

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

0

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

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

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь