【查漏补缺】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?

posted @ 2019-04-21 15:07  CoDeleven  阅读(8371)  评论(0编辑  收藏  举报