【java】File,file.getPath(), getAbsolutePath(), getCanonicalPath()区别

来源:互联网 发布:c语言中开方怎么表示 编辑:程序博客网 时间:2024/05/16 23:44

这几个方法对于没有仔细研究过的人来说确实有些困扰,难以清晰地搞懂他们的区别。

其实,我想说这些难度都来自我们对File类认知的偏差,不知道大家怎么理解的,我大学里面没有深究过File,一直把它当作是“文件”这一个概念在java世界里的抽象,实则不然。

今天拿起java的jdk查阅后发现下面的定义:

An abstract representation of file and directory pathnames.
也即是说,File不是“文件”的抽象。而是一个路径名的抽象!!!我们new出来的File实例,仅仅是一个路径名,要想对文件操作,在java中其实是通过管道对路径名来操作。

还有一个概念需要区分,就是abstract pathname和pathname二者。我根据jdk的理解是,我们在构造一个File时,肯定是传递一个代表路径的字符串,比如A,因为java的平台无关性,所以这个A肯定是无关操纵系统的,只要能让jvm识别出来字符串的层级关系就行,而不用关心什么Unix系统是“/”,windows系统是“\\”,因为我们在用自己的方式告诉jvm如何创建一个File,而java语言是平台无关的!所以我们在用的时候就不应该关心操作系统!如果要是关心了,那么也就是说我的程序在Linux上运行时,要这样写:

File f = new File("./f.txt");
然后过几天我要在windows上运行了,这是就得改成:

File f = new File(".\\f.txt");

这显然不符合java的设计理念“run anywhere”。

不妨来试试:

我在windows操作系统上运行的程序,

import java.io.File;public class Main {public static void main(String[] args) {        File f1 = new File("../F1.txt");        System.out.println(f1.getPath());                File f2 = new File("..\\F1.txt");        System.out.println(f2.getPath());                File f3 = new File("..///////F1.txt");        System.out.println(f3.getPath());                File f4 = new File("..///??'F1.txt");        System.out.println(f4.getPath());}}
结果:


也就是说我们构造File时用的是“pathname”,与平台无关
,根本不用关心操作系统,只要传递合适的通俗的可以代表目录分割的符号就可以(这个我还没精确搞懂是哪些,不过“/”,"\\"斜杠之类的肯定可以),而真正要去处理与操作系统相关的问题的正是File类自己,它可以接收一个我们给的与操作系统无关的string,然后根据这个路径的string再创建一个路径名的抽象,即File的实例,这个实例内部含有了与操作系统相关的路径名,我们可以通过它的方法来得到与操作系统相关的路径名,也就是说File类帮我们完成了转换。与操作系统相关的路径名jdk把它叫做“abstract pathname”。

而标题中的第一个方法就是干这个的。


file.getPath():Converts this abstract pathname into a pathname string. The resulting string uses the default name-separator character to separate the names in the name sequence.

这是jdk的解释,能够返回abstract pathname的字符串形式,使用的是与操作系统相关的分隔符。说白了这个方法就是返回构造file时用的路径字符串经过转换以后的与操作系统相关路径。与什么相对不相对没有任何关系,传什么我就转什么,然后返回。


getAbsolutePath():Returns the absolute pathname string of this abstract pathname.

If this abstract pathname is already absolute, then the pathname string is simply returned as if by the getPath() method. If this abstract pathname is the empty abstract pathname then the pathname string of the current user directory, which is named by the system property user.dir, is returned. Otherwise this pathname is resolved in a system-dependent way. On UNIX systems, a relative pathname is made absolute by resolving it against the current user directory. On Microsoft Windows systems, a relative pathname is made absolute by resolving it against the current directory of the drive named by the pathname, if any; if not, it is resolved against the current user directory.

意思是,如果给的参数就是绝对路径了,那么返回getPath()。如果不是,那就加上user.dir的路径,然后用与系统相关的分隔符分开,返回。与getPath相比,就是多了user.dir路径(这个路径一般是项目的根目录)。


getCanonicalPath():更好理解了,jdk原文解释不贴了,直接字面意思就猜得出,就是把getAbsolutePath()的结果再转换一次,去掉里面的"../"之类的东西,返回唯一的形式,就是只包含文件夹实际名字加分隔符的路径,没有父目录这样的东西在里面。


0 0