比较Java中的getPath()、getAbsolutePath()和getCanonicalPath()

2025/04/06

1. 概述

java.io.File类有3种方法-getPath()、getAbsolutePath()和getCanonicalPath()来获取文件系统路径。

在本文中,我们将快速了解它们之间的区别,并讨论一个你可以选择使用其中一个的用例。

2. 方法定义和示例

让我们首先回顾一下这3种方法的定义,以及基于用户主目录中存在以下目录结构的示例:

|-- tuyucheng
    |-- tuyucheng.txt
    |-- foo
    |   |-- foo-one.txt
    |   -- foo-two.txt
    -- bar
        |-- bar-one.txt
        |-- bar-two.txt
        -- baz
            |-- baz-one.txt
            -- baz-two.txt

2.1 getPath()

简单地说,getPath()返回文件抽象路径名的字符串表示形式,这实际上是传递给File构造函数的路径名

因此,如果File对象是使用相对路径创建的,则getPath()方法的返回值也将是相对路径。

如果我们从{user.home}/tuyucheng目录调用以下代码:

File file = new File("foo/foo-one.txt");
String path = file.getPath();

路径path将具有以下值:

foo/foo-one.txt  // on Unix systems
foo\foo-one.txt  // on Windows systems

请注意,对于Windows系统,名称分隔符已从传递给构造函数的正斜杠(/)字符更改为反斜杠(\)字符,这是因为返回的String始终使用平台的默认名称分隔符

2.2 getAbsolutePath()

getAbsolutePath()方法在解析当前用户目录的路径后返回文件的路径名-这称为绝对路径名。因此,对于我们之前的示例,file.getAbsolutePath()将返回:

/home/username/tuyucheng/foo/foo-one.txt     // on Unix systems
C:\Users\username\tuyucheng\foo\foo-one.txt  // on Windows systems

此方法仅解析相对路径的当前目录,简写表示(例如”.”和”..”)不会进一步解析。因此,当我们从目录{user.home}/tuyucheng执行以下代码时:

File file = new File("bar/baz/../bar-one.txt");
String path = file.getAbsolutePath();

变量path的值将是:

/home/username/tuyucheng/bar/baz/../bar-one.txt      // on Unix systems
C:\Users\username\tuyucheng\bar\baz\..\bar-one.txt   // on Windows systems

2.3 getCanonicalPath()

getCanonicalPath()方法更进一步,根据目录结构解析绝对路径名以及“.”和“..”等简写或冗余名称。它还解析Unix系统上的符号链接,并将驱动器号转换为Windows系统上的标准大小写。

因此对于前面的示例,getCanonicalPath()方法将返回:

/home/username/tuyucheng/bar/bar-one.txt     // on Unix systems
C:\Users\username\tuyucheng\bar\bar-one.txt  // on Windows systems

我们再举一个例子,假设当前目录为${user.home}/tuyucheng,并使用参数new File(“bar/baz/./baz-one.txt”)创建File对象,则getCanonicalPath()的输出将是:

/home/username/tuyucheng/bar/baz/baz-one.txt     // on Unix systems
C:\Users\username\tuyucheng\bar\baz\baz-one.txt  // on Windows Systems

值得一提的是,文件系统上的单个文件可以有无数个绝对路径,因为简写表示法有无数种用法。但是,规范路径将始终是唯一的,因为所有此类表示法都已解析。

与后两种方法不同,getCanonicalPath()可能会抛出IOException,因为它需要文件系统查询。

例如,在Windows系统上,如果我们创建一个具有非法字符的File对象,解析规范路径将抛出IOException:

new File("*").getCanonicalPath();

3. 用例

假设我们正在编写一个方法,将File对象作为参数并将其完全限定名称保存到数据库中,我们不知道路径是相对路径还是包含简写。在这种情况下,我们可能更倾向使用getCanonicalPath()。

但是,由于getCanonicalPath()会读取文件系统,因此会产生性能成本。如果我们确定没有冗余名称或符号链接并且驱动器字母大小写是标准化的(如果使用Windows操作系统),那么我们应该更倾向使用getAbsolutePath()。

4. 总结

在本快速教程中,我们介绍了获取文件系统路径的三种File方法之间的差异。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章