Не забывайте, Path.toAbsolutePath().normalize()что это хорошая середина между каноническим (реальным) путем и только абсолютным путем.
eckes
Ответы:
625
Рассмотрим эти имена файлов:
C:\temp\file.txt - Это путь, абсолютный путь и канонический путь.
.\file.txt- Это путь. Это не абсолютный и не канонический путь.
C:\temp\myapp\bin\..\\..\file.txt- Это путь и абсолютный путь. Это не канонический путь.
Канонический путь - это всегда абсолютный путь.
Преобразование из пути в канонический путь делает его абсолютным (обычно это привязка к текущему рабочему каталогу, например, ./file.txtстановится c:/temp/file.txt). Канонический путь к файлу просто «очищает» путь, удаляя и разрешая такие вещи, как ..\и разрешая символические ссылки (в unixes).
Также обратите внимание на следующий пример с nio.Paths:
FWIW, это не дано, C:\temp\file.txtэто канонический путь - временный каталог может быть мягкой ссылкой файловой системы или жесткой ссылкой (соединение в NTFS), а file.txt может быть мягкой ссылкой. Я не знаю, могут ли файловые системы различать жесткие ссылки на файлы.
Лоуренс Дол
1
На самом деле путь не учитывает эти проблемы или существование каких-либо компонентов, а только его синтаксис.
побег-ООО
Это так, канонический путь (в отличие от нормализованного пути) попадает в файловую систему.
eckes
1
В принципе, я не вижу причины, по которой следует использовать getAbsolutePath()вместо getCanonicalPath(). Это даже выглядит лучше, потому что канонический автоматически разрешает эти ../части.
Scadge
Не забывайте, что getCanonicalPathбросает какое- IOExceptionто время getAbsolutePathнет, если это соображение.
заброшенная корзина
129
Лучший способ почувствовать такие вещи - попробовать их:
import java.io.File;publicclassPathTesting{publicstaticvoid main(String[] args){File f =newFile("test/.././file.txt");System.out.println(f.getPath());System.out.println(f.getAbsolutePath());try{System.out.println(f.getCanonicalPath());}catch(Exception e){}}}
Итак, getPath()дает вам путь, основанный на объекте File, который может быть или не быть относительным; getAbsolutePath()дает вам абсолютный путь к файлу; и getCanonicalPath()дает вам уникальный абсолютный путь к файлу. Обратите внимание, что существует огромное количество абсолютных путей, которые указывают на один и тот же файл, но только один канонический путь.
Когда использовать каждый? Зависит от того, что вы пытаетесь выполнить, но если вы пытаетесь увидеть Files, указывают ли два файла на один и тот же файл на диске, вы можете сравнить их канонические пути. Всего один пример.
Можно утверждать, что Java неправильно реализовала «абсолютный» путь; он действительно должен был удалить все элементы относительного пути в абсолютном пути. Каноническая форма будет тогда удалять любые ссылки FS или соединения в пути.
Лоуренс Дол
but if you were trying to see if two Files are pointing at the same file on diskКак? пример пожалуйста?
Асиф Муштак
@UnKnown: вы бы использовали для этого канонический путь.
Лоуренс Дол
67
Короче говоря:
getPath()получает строку пути, с которой Fileбыл построен объект, и это может быть относительный текущий каталог.
getAbsolutePath() получает строку пути после разрешения ее относительно текущего каталога, если он относительный, в результате чего получается полный путь.
getCanonicalPath()получает строку пути после разрешения любого относительного пути к текущему каталогу и удаляет все относительные пути ( .и ..) и любые ссылки файловой системы, чтобы вернуть путь, который файловая система считает каноническим средством для ссылки на объект файловой системы, на который она указывает.
Кроме того, каждый из них имеет файловый эквивалент, который возвращает соответствующий Fileобъект.
getPath()возвращает путь, использованный для создания Fileобъекта. Это возвращаемое значение не изменяется в зависимости от местоположения, в котором оно выполняется (результаты ниже для окон, разделители, очевидно, отличаются в других местах)
File f1 =newFile("/some/path");String path = f1.getPath();// will return "\some\path"File dir =newFile("/basedir");File f2 =newFile(dir,"/some/path");
path = f2.getPath();// will return "\basedir\some\path"File f3 =newFile("./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()полезно, чтобы найти расположение файловой системы, и getCanonicalPath()особенно полезно, чтобы проверить, совпадают ли два файла.
Можете ли вы дать мне какой-нибудь пример этого? getCanonicalPath() is particularly useful to check if two files are the same.
Асиф Муштак
20
Главное, чтобы вы могли поразмыслить над тем, что Fileкласс пытается представить представление о том, что Sun любит называть «иерархическими путями» (в основном это путь, похожий на c:/foo.txtили /usr/muggins). Вот почему вы создаете файлы с точки зрения путей. Все операции, которые вы описываете, являются операциями с этим «путем».
getPath()извлекает путь, по которому был создан файл ( ../foo.txt)
getAbsolutePath()извлекает путь, с помощью которого был создан файл, но включает информацию о текущем каталоге, если путь относительный ( /usr/bobstuff/../foo.txt)
getCanonicalPath()пытается получить уникальное представление об абсолютном пути к файлу. Это устраняет косвенность от ".." и "." ссылки ( /usr/foo.txt).
Заметьте, я говорю попытки - при формировании канонического пути виртуальная машина может бросить IOException. Обычно это происходит потому, что он выполняет некоторые операции с файловой системой, любая из которых может дать сбой.
Я нахожу, что мне редко приходится использовать, getCanonicalPath()но, если в Windows указан файл с именем файла в формате DOS 8.3, например, java.io.tmpdirвозвращаемое свойство System, этот метод возвращает «полное» имя файла.
Path.toAbsolutePath().normalize()
что это хорошая середина между каноническим (реальным) путем и только абсолютным путем.Ответы:
Рассмотрим эти имена файлов:
C:\temp\file.txt
- Это путь, абсолютный путь и канонический путь..\file.txt
- Это путь. Это не абсолютный и не канонический путь.C:\temp\myapp\bin\..\\..\file.txt
- Это путь и абсолютный путь. Это не канонический путь.Канонический путь - это всегда абсолютный путь.
Преобразование из пути в канонический путь делает его абсолютным (обычно это привязка к текущему рабочему каталогу, например,
./file.txt
становитсяc:/temp/file.txt
). Канонический путь к файлу просто «очищает» путь, удаляя и разрешая такие вещи, как..\
и разрешая символические ссылки (в unixes).Также обратите внимание на следующий пример с nio.Paths:
Хотя оба пути относятся к одному и тому же местоположению, выходные данные будут совершенно разными:
источник
C:\temp\file.txt
это канонический путь - временный каталог может быть мягкой ссылкой файловой системы или жесткой ссылкой (соединение в NTFS), а file.txt может быть мягкой ссылкой. Я не знаю, могут ли файловые системы различать жесткие ссылки на файлы.getAbsolutePath()
вместоgetCanonicalPath()
. Это даже выглядит лучше, потому что канонический автоматически разрешает эти../
части.getCanonicalPath
бросает какое-IOException
то времяgetAbsolutePath
нет, если это соображение.Лучший способ почувствовать такие вещи - попробовать их:
Ваш вывод будет примерно таким:
Итак,
getPath()
дает вам путь, основанный на объекте File, который может быть или не быть относительным;getAbsolutePath()
дает вам абсолютный путь к файлу; иgetCanonicalPath()
дает вам уникальный абсолютный путь к файлу. Обратите внимание, что существует огромное количество абсолютных путей, которые указывают на один и тот же файл, но только один канонический путь.Когда использовать каждый? Зависит от того, что вы пытаетесь выполнить, но если вы пытаетесь увидеть
Files
, указывают ли два файла на один и тот же файл на диске, вы можете сравнить их канонические пути. Всего один пример.источник
but if you were trying to see if two Files are pointing at the same file on disk
Как? пример пожалуйста?Короче говоря:
getPath()
получает строку пути, с которойFile
был построен объект, и это может быть относительный текущий каталог.getAbsolutePath()
получает строку пути после разрешения ее относительно текущего каталога, если он относительный, в результате чего получается полный путь.getCanonicalPath()
получает строку пути после разрешения любого относительного пути к текущему каталогу и удаляет все относительные пути (.
и..
) и любые ссылки файловой системы, чтобы вернуть путь, который файловая система считает каноническим средством для ссылки на объект файловой системы, на который она указывает.Кроме того, каждый из них имеет файловый эквивалент, который возвращает соответствующий
File
объект.источник
getPath()
возвращает путь, использованный для созданияFile
объекта. Это возвращаемое значение не изменяется в зависимости от местоположения, в котором оно выполняется (результаты ниже для окон, разделители, очевидно, отличаются в других местах)getAbsolutePath()
разрешит путь в зависимости от места выполнения или диска. Так что если бежать изc:\test
:getCanonicalPath()
зависит от системы. Это разрешит уникальное местоположение, которое представляет путь. Так что если у вас есть какие-либо "." В пути, они обычно будут удалены.Что касается того, когда их использовать. Это зависит от того, чего вы пытаетесь достичь.
getPath()
полезно для мобильности.getAbsolutePath()
полезно, чтобы найти расположение файловой системы, иgetCanonicalPath()
особенно полезно, чтобы проверить, совпадают ли два файла.источник
getCanonicalPath() is particularly useful to check if two files are the same.
Главное, чтобы вы могли поразмыслить над тем, что
File
класс пытается представить представление о том, что Sun любит называть «иерархическими путями» (в основном это путь, похожий наc:/foo.txt
или/usr/muggins
). Вот почему вы создаете файлы с точки зрения путей. Все операции, которые вы описываете, являются операциями с этим «путем».getPath()
извлекает путь, по которому был создан файл (../foo.txt
)getAbsolutePath()
извлекает путь, с помощью которого был создан файл, но включает информацию о текущем каталоге, если путь относительный (/usr/bobstuff/../foo.txt
)getCanonicalPath()
пытается получить уникальное представление об абсолютном пути к файлу. Это устраняет косвенность от ".." и "." ссылки (/usr/foo.txt
).Заметьте, я говорю попытки - при формировании канонического пути виртуальная машина может бросить
IOException
. Обычно это происходит потому, что он выполняет некоторые операции с файловой системой, любая из которых может дать сбой.источник
Я нахожу, что мне редко приходится использовать,
getCanonicalPath()
но, если в Windows указан файл с именем файла в формате DOS 8.3, например,java.io.tmpdir
возвращаемое свойство System, этот метод возвращает «полное» имя файла.источник