Рассмотрим эти имена файлов:
C: \ temp \ file.txt
- это путь, абсолютный путь и канонический путь.
. \ File. txt
- Это путь. Это не абсолютный и не канонический путь.
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
getPath ()
возвращает путь, используемый для создания объекта File
. Это возвращаемое значение не изменяется в зависимости от местоположения, в котором оно запускается (результаты ниже для окон, разделители, очевидно, отличаются в других местах)
File f1 = new File("/some/path");
String path = f1.getPath(); // will return "\some\path"
File dir = new File("/basedir");
File f2 = new File(dir, "/some/path");
path = f2.getPath(); // will return "\basedir\some\path"
File f3 = new File("./some/path");
path = f3.getPath(); // will return ".\some\path"
getAbsolutePath ()
разрешит путь на основе местоположения выполнения или диска. Таким образом, при запуске из c: \ test
:
path = f1.getAbsolutePath(); // will return "c:\some\path"
path = f2.getAbsolutePath(); // will return "c:\basedir\some\path"
path = f3.getAbsolutePath(); // will return "c:\test\.\basedir\some\path"
getCanonicalPath ()
зависит от системы. Это разрешит уникальное местоположение, которое представляет путь. Так что, если у вас есть какие-либо "." В пути, они обычно удаляются.
Что касается того, когда их использовать. Это зависит от того, чего вы пытаетесь достичь. getPath ()
полезен для переносимости. getAbsolutePath ()
полезен для поиска местоположения файловой системы,
Лучший способ, который я нашел, чтобы прочувствовать подобные вещи, - это попробовать их :
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) {}
}
}
Ваш результат будет примерно таким:
test\..\.\file.txt
C:\projects\sandbox\trunk\test\..\.\file.txt
C:\projects\sandbox\trunk\file.txt
Итак, getPath ()
дает вам путь на основе объекта File, который может быть или не быть относительным; getAbsolutePath ()
дает вам абсолютный путь к файлу; а getCanonicalPath ()
дает вам уникальный абсолютный путь к файлу. Обратите внимание, что существует огромное количество абсолютных путей, указывающих на один и тот же файл, но только один канонический путь.
Когда использовать каждый? Зависит от того, что вы пытаетесь выполнить, но если вы пытались увидеть, указывают ли два файла
на один и тот же файл на диске, вы можете сравнить их канонические пути. Только один пример.
Главное, что вам нужно знать, это то, что класс File
пытается представить представление о том, что Sun любит называть «иерархическими именами путей» (в основном путь вроде c: /foo.txt
или / usr / muggins
). Вот почему вы создаете файлы с точки зрения путей. Все операции, которые вы описываете, относятся к этому «имени пути».
getPath ()
извлекает путь, по которому был создан файл ( ../ foo.txt
) getAbsolutePath ()
выбирает путь, по которому был создан файл, но включает информацию о текущем каталоге, если путь является относительным ( / usr / bobstuff /../ foo.txt
) getCanonicalPath ()
пытается получить уникальное представление абсолютного пути к файлу. Это устраняет косвенное указание на ".." и "." ссылки ( /usr/foo.txt
). Примечание. Я говорю попыток - при формировании канонического пути виртуальная машина может генерировать исключение IOException
. Обычно это происходит из-за того, что он выполняет некоторые операции с файловой системой, любая из которых может дать сбой.
Вкратце:
getPath ()
получает строку пути, с которой был создан объект File
, и это может быть относительный текущий каталог. ] getAbsolutePath ()
получает строку пути после сопоставления ее с текущим каталогом, если она относительная, в результате чего получается полный путь. getCanonicalPath ()
получает строку пути после сопоставления любого относительного пути с текущим каталогом , и удаляет все относительные пути (.
и ..
), а также любые ссылки на файловую систему для возврата пути, который файловая система считает каноническим средством ссылки на объект файловой системы, к которому он указывает. Кроме того, каждый из них имеет эквивалент File, который возвращает соответствующий объект File
.