背景
在學習Idea的插件開發時,用到了相關的VirtualFileSystem
這個東西,里面的VirtualFile
有一個getCanonicalPath()
方法引起了我的注意,我發現我不知道——
科普
首先知曉一下幾個名詞——路徑、絕對路徑/相對路徑、規范路徑
然后考慮以下幾種路徑:
- c:\temp\file.txt
- .\file.txt
- c:\temp\MyApp\bin\..\..\file.txt
第一類,屬於路徑,絕對路徑,規范路徑
第二類,屬於路徑,相對路徑
第三類,屬於路徑,絕對路徑
我們結合自己的開發經驗,發現絕大多數情況都已經被覆蓋到了,那么我們可以大致推測,路徑
包含絕對路徑/相對路徑
,絕對路徑
包含規范路徑
,而相對路徑
不包含規范路徑
。
實戰
/* -------這是一個規范路徑的代碼------- */
File file = new File("C:\\Users\\W650\\Desktop\\701Studio\\app.js");
System.out.println("file.getAbsolutePath() -> " + file.getAbsolutePath());
System.out.println("file.getCanonicalPath() -> " + file.getCanonicalPath());
System.out.println("file.getPath() -> " + file.getPath());
/* -------輸出------- */
file.getAbsolutePath() -> C:\Users\W650\Desktop\701Studio\app.js
file.getCanonicalPath() -> C:\Users\W650\Desktop\701Studio\app.js
file.getPath() -> C:\Users\W650\Desktop\701Studio\app.js
/* -------這是一個絕對路徑的代碼(但不規范)------- */
File file = new File("C:\\Users\\W650\\Desktop\\701Studio\\utils\\..\\app.js");
System.out.println("file.getAbsolutePath() -> " + file.getAbsolutePath());
System.out.println("file.getCanonicalPath() -> " + file.getCanonicalPath());
System.out.println("file.getPath() -> " + file.getPath());
/* -------輸出------- */
file.getAbsolutePath() -> C:\Users\W650\Desktop\701Studio\utils\..\app.js
file.getCanonicalPath() -> C:\Users\W650\Desktop\701Studio\app.js
file.getPath() -> C:\Users\W650\Desktop\701Studio\utils\..\app.js
/* -------這是一個相對路徑的代碼------- */
File file = new File("..\\..\\..\\Test.txt");
System.out.println("file.getAbsolutePath() -> " + file.getAbsolutePath());
System.out.println("file.getCanonicalPath() -> " + file.getCanonicalPath());
System.out.println("file.getPath() -> " + file.getPath());
/* -------輸出------- */
file.getAbsolutePath() -> E:\commonWorkspace\IdeaPluginDevGuide\DevGuide-VirtualFileSystem\..\..\..\Test.txt
file.getCanonicalPath() -> E:\Test.txt
file.getPath() -> ..\..\..\Test.txt
區別與聯系
Returns the canonical pathname string of this abstract pathname.
<p> A canonical pathname is both absolute and unique. The precise
definition of canonical form is system-dependent. This method first
converts this pathname to absolute form if necessary, as if by invoking the
{@link #getAbsolutePath} method, and then maps it to its unique form in a
system-dependent way. This typically involves removing redundant names
such as <tt>"."</tt> and <tt>".."</tt> from the pathname, resolving
symbolic links (on UNIX platforms), and converting drive letters to a
standard case (on Microsoft Windows platforms).
<p> Every pathname that denotes an existing file or directory has a
unique canonical form. Every pathname that denotes a nonexistent file
or directory also has a unique canonical form. The canonical form of
the pathname of a nonexistent file or directory may be different from
the canonical form of the same pathname after the file or directory is
created. Similarly, the canonical form of the pathname of an existing
file or directory may be different from the canonical form of the same
pathname after the file or directory is deleted.
大概就是說getCanonicalPath()
獲得的格式是和系統相關的(Linux和Windows下不一樣),在執行過程中會將當前的path
轉換成absolute path
,然后去掉absolute path
內重復的 .和 ..等等。
最后一段有點不理解,就是說
* 表示現有文件或目錄的每個路徑名都有一個惟一的規范形式。
* 表示非存在文件或目錄的每個路徑名也有一個惟一的規范形式。
* 非存在文件或目錄路徑名的規范形式可能不同於創建文件或目錄之后同一路徑名的規范形式。
* 同樣,現有文件或目錄路徑名的規范形式可能不同於刪除文件或目錄之后同一路徑名的規范形式。
結論
- 路徑包含絕對路徑和相對路徑,絕對路徑又包含了規范路徑。
getPath()
會返回給用戶創建File的路徑,getAbsolutePath
會依據調用該方法的類所在的路徑 + 文件分隔符 + 創建File的路徑
構造絕對路徑,getCanonicalPath()
一定返回規范的路徑。
參考
What's the difference between getPath(), getAbsolutePath(), and getCanonicalPath() in Java?