Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java – 比较Java中的getPath()、getAbsolutePath()和getCanonicalPath()

最后修改: 2017年 5月 21日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

The java.io.File class has three methods — getPath(), getAbsolutePath() and getCanonicalPath() — to obtain the filesystem path.

java.io.File类有三个方法–getPath()getAbsolutePath()getCanonicalPath()–来获取文件系统路径。

In this article, we’ll have a quick look at the differences between them and discuss a use case where you may choose to use one over the others.

在这篇文章中,我们将快速看一下它们之间的区别,并讨论一个你可能选择使用其中一个而不是其他的用例。

2. Method Definitions and Examples

2.方法的定义和例子

Let’s start by going over the definitions of the three methods, along with examples based on having the following directory structure present in the user’s home directory:

让我们先来看看这三种方法的定义,以及基于用户主目录中存在以下目录结构的例子。

|-- baeldung
    |-- baeldung.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()

2.1. getPath()

Simply put, getPath() returns the String representation of the file’s abstract pathname. This is essentially the pathname passed to the File constructor.

简单地说,getPath()返回文件的抽象路径名的String表示。这基本上是传递给File构造函数的路径名

So, if the File object was created using a relative path, the returned value from getPath() method would also be a relative path.

因此,如果文件对象是使用相对路径创建的,那么getPath()方法的返回值也将是一个相对路径。

If we invoke the following code from the {user.home}/baeldung directory:

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

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

The path variable would have the value:

path变量的值将是。

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

Notice that for the Windows system, the name-separator character has changed from the forward slash(/) character, which was passed to the constructor, to the backslash (\) character. This is because the returned String always uses the platform’s default name-separator character.

请注意,对于Windows系统来说,名字的分隔符已经从传递给构造函数的正斜杠(/)字符变成了反斜杠(\)字符。这是因为返回的String总是使用平台的默认名称分隔符

2.2. getAbsolutePath()

2.2.getAbsolutePath()

The getAbsolutePath() method returns the pathname of the file after resolving the path for the current user directory — this is called an absolute pathname. So, for our previous example, file.getAbsolutePath() would return:

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

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

This method only resolves the current directory for a relative path. Shorthand representations (such as “.” and “..”) are not resolved further. Hence when we execute the following code from the directory {user.home}/baeldung:

这个方法只对相对路径的当前目录进行解析。速记表示法(如”.”和”.”)不会被进一步解析。因此,当我们从目录{user.home}/baeldung:执行以下代码时

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

The value of the variable path would be:

变量path的值将是。

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

2.3. getCanonicalPath()

2.3.getCanonicalPath()

The getCanonicalPath() method goes a step further and resolves the absolute pathname as well as the shorthands or redundant names like “.” and “.. as per the directory structure. It also resolves symbolic links on Unix systems and converts the drive letter to a standard case on Windows systems.

getCanonicalPath()方法更进一步,根据目录结构解析绝对路径名以及诸如”.“和”“等速记或多余的名称。在Unix系统中,它还可以解决符号链接,在Windows系统中,将驱动器字母转换为标准大小写

So for the previous example, getCanonicalPath() method would return:

所以对于前面的例子,getCanonicalPath()方法将返回。

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

Let’s take another example. Given current directory as ${user.home}/baeldung and File object created using the parameter new File(“bar/baz/./baz-one.txt”), the output for getCanonicalPath() would be:

让我们再举个例子。鉴于当前目录为${user.home}/baeldung,以及使用参数new File(“bar/baz/./baz-one.txt”)创建的File对象,getCanonicalPath()的输出将是。

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

It’s worth mentioning that a single file on the filesystem can have an infinite number of absolute paths since there’s an infinite number of ways shorthand representations can be used. However, the canonical path will always be unique since all such representations are resolved.

值得一提的是,文件系统中的一个文件可以有无限多的绝对路径,因为有无限多的速记表示方法可以使用。然而,规范路径将始终是唯一的,因为所有这些表示方法都被解决。

Unlike the last two methods, getCanonicalPath() may throw IOException because it requires filesystem queries.

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

For example, on Windows systems, if we create a File object with one of the illegal characters, resolving the canonical path will throw an IOException:

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

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

3. Use Case

3.使用案例

Let’s say we’re writing a method that takes in a File object as a parameter and saves its fully qualified name into a database. We don’t know whether the path is relative or contains shorthands. In this case, we may want to use getCanonicalPath().

假设我们正在编写一个方法,该方法接收一个文件对象作为参数,并将其完全合格的名称保存到一个数据库中。我们不知道该路径是相对的还是包含短语。在这种情况下,我们可能想使用getCanonicalPath()

However, since getCanonicalPath() reads the filesystem, it comes at a performance cost. If we are sure that there are no redundant names or symbolic links and drive letter case is standardized (if using a Windows OS), then we should prefer using getAbsoultePath().

然而,由于getCanonicalPath()会读取文件系统,所以它需要付出性能代价。如果我们确定没有多余的名称或符号链接,并且驱动器的大小写是标准化的(如果使用Windows操作系统),那么我们应该更喜欢使用getAbsoultePath()

4. Conclusion

4.结论

In this quick tutorial, we covered the differences between the three File methods to get filesystem path. We have also shown a use case where one method may be preferred over the other.

在这个快速教程中,我们介绍了获取文件系统路径的三种File方法的区别。我们还展示了一个用例,其中一种方法可能比另一种方法更受欢迎。

A Junit test class demonstrating the examples of this article can be found over on GitHub.

Junit测试类演示了本文的例子,可以在GitHub上找到over