【查漏補缺】File的path、absolutePath和canonicalPath的區別


背景

在學習Idea的插件開發時,用到了相關的VirtualFileSystem這個東西,里面的VirtualFile有一個getCanonicalPath()方法引起了我的注意,我發現我不知道——

科普

首先知曉一下幾個名詞——路徑絕對路徑/相對路徑規范路徑

然后考慮以下幾種路徑:

  1. c:\temp\file.txt
  2. .\file.txt
  3. 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 內重復的 ...等等。

最后一段有點不理解,就是說

 * 表示現有文件或目錄的每個路徑名都有一個惟一的規范形式。
 * 表示非存在文件或目錄的每個路徑名也有一個惟一的規范形式。
 * 非存在文件或目錄路徑名的規范形式可能不同於創建文件或目錄之后同一路徑名的規范形式。
 * 同樣,現有文件或目錄路徑名的規范形式可能不同於刪除文件或目錄之后同一路徑名的規范形式。 

結論

  1. 路徑包含絕對路徑相對路徑絕對路徑又包含了規范路徑。
  2. getPath()會返回給用戶創建File的路徑getAbsolutePath會依據調用該方法的類所在的路徑 + 文件分隔符 + 創建File的路徑構造絕對路徑,getCanonicalPath()一定返回規范的路徑。

參考

What's the difference between getPath(), getAbsolutePath(), and getCanonicalPath() in Java?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM