Java中的getPath(),getAbsolutePath()和getCanonicalPath()有什么区别?

knt*_*knt 567 java

什么之间的区别getPath(),getAbsolutePath()以及getCanonicalPath()在Java中?

我什么时候使用每一个?

nos*_*nos 615

考虑这些文件名:

C:\temp\file.txt - 这是一条路径,一条绝对路径和一条规范路径.

.\file.txt - 这是一条路.它既不是绝对的道路,也不是规范的道路.

C:\temp\myapp\bin\..\\..\file.txt - 这是一条路径和绝对路径.这不是一个规范的道路.

规范路径始终是绝对路径.

从路径转换为规范路径使其成为绝对路径(通常在当前工作目录上添加,例如./file.txt变为c:/temp/file.txt).文件的规范路径只是"净化"路径,删除和解析类似的东西..\并解析符号链接(在unixes上).

另请注意以下使用nio.Paths的示例:

String canonical_path_string = "C:\\Windows\\System32\\";
String absolute_path_string = "C:\\Windows\\System32\\drivers\\..\\";

System.out.println(Paths.get(canonical_path_string).getParent());
System.out.println(Paths.get(absolute_path_string).getParent());
Run Code Online (Sandbox Code Playgroud)

虽然两个路径都指向相同的位置,但输出将完全不同:

C:\Windows
C:\Windows\System32\drivers
Run Code Online (Sandbox Code Playgroud)

  • FWIW,它不是'C:\ temp\file.txt`是一个规范路径 - 临时目录可能是文件系统软链接或硬链接(NTFS中的联结),而file.txt可能是软的链接.我不知道文件系统是否可以区分硬链接到文件. (10认同)
  • 不要忘记 `getCanonicalPath` 会抛出一个 `IOException` 而 `getAbsolutePath` 不会,如果这是一个考虑因素的话。 (4认同)
  • 基本上,我看不出为什么应该使用 `getAbsolutePath()` 而不是 `getCanonicalPath()` 的原因。它甚至看起来更好,因为规范的会自动解析那些“../”部分。 (2认同)

dav*_*351 128

我发现对这样的事情感觉最好的方法就是尝试一下:

import java.io.File;
public class PathTesting {
    public static void main(String [] args) {
        File f = new File("test/.././file.txt");
        System.out.println(f.getPath());
        System.out.println(f.getAbsolutePath());
        try {
            System.out.println(f.getCanonicalPath());
        }
        catch(Exception e) {}
    }
}
Run Code Online (Sandbox Code Playgroud)

你的输出将是这样的:

test\..\.\file.txt
C:\projects\sandbox\trunk\test\..\.\file.txt
C:\projects\sandbox\trunk\file.txt
Run Code Online (Sandbox Code Playgroud)

所以,getPath()给你一个基于File对象的路径,它可能是也可能不是相对的; getAbsolutePath()为您提供文件的绝对路径; 并getCanonicalPath()为您提供文件的唯一绝对路径.请注意,存在大量指向同一文件的绝对路径,但只有一条规范路径.

什么时候使用?取决于你想要完成什么,但如果你试图看看两个Files是否指向磁盘上的同一个文件,你可以比较它们的规范路径.只是一个例子.

  • 有争议的是Java让它实现了一个"绝对"的错误路径; 它确实应该删除绝对路径中的任何相对路径元素.然后,规范形式将删除路径中的任何FS链接或联结. (7认同)

Law*_*Dol 64

简而言之:

  • getPath()获取File构造对象的路径字符串,它可能是相对当前目录.
  • getAbsolutePath() 如果它是相对的,则在解析当前目录后获取路径字符串,从而产生完全限定的路径.
  • getCanonicalPath()在解析当前目录的任何相对路径之后获取路径字符串,并删除任何相对路径(...),并删除任何文件系统链接以返回文件系统认为规范意味着引用它指向的文件系统对象的路径.

此外,每个都有一个File等效项,返回相应的File对象.

  • 我发现唯一清晰如冰的解释。谢谢! (2认同)

Ric*_*ler 36

getPath()返回用于创建File对象的路径.此返回值不会根据其运行位置而更改(以下结果适用于Windows,分隔符在其他位置显然不同)

File f1 = new File("/some/path");
String path = f1.getPath(); // will return "\some\path"

File dir = new File("/basedir");
File f2 = new File(dir, "/some/path");
path = f2.getPath(); // will return "\basedir\some\path"

File f3 = new File("./some/path");
path = f3.getPath(); // will return ".\some\path"
Run Code Online (Sandbox Code Playgroud)

getAbsolutePath()将根据执行位置或驱动器解析路径.所以,如果从运行c:\test:

path = f1.getAbsolutePath(); // will return "c:\some\path"
path = f2.getAbsolutePath(); // will return "c:\basedir\some\path"
path = f3.getAbsolutePath(); // will return "c:\test\.\basedir\some\path"
Run Code Online (Sandbox Code Playgroud)

getCanonicalPath()是系统依赖的.它将解析路径所代表的唯一位置.因此,如果路径中有任何".",则通常会将其删除.

至于何时使用它们.这取决于你想要达到的目标.getPath()对于可移植性很有用.getAbsolutePath()查找文件系统位置getCanonicalPath()很有用,对于检查两个文件是否相同特别有用.


but*_*ken 19

让你头脑发热的重要一点是,File该类试图表示Sun喜欢称之为"分层路径名"的视图(基本上是类似c:/foo.txt或路径/usr/muggins).这就是您根据路径创建文件的原因.您描述的操作是对此"路径名"的所有操作.

  • getPath()获取使用(../foo.txt)创建文件的路径
  • getAbsolutePath()获取创建文件的路径,但如果路径是相对的,则包含有关当前目录的信息(/usr/bobstuff/../foo.txt)
  • getCanonicalPath() 尝试获取文件的绝对路径的唯一表示.这消除了".."和"."的间接方向.引用(/usr/foo.txt).

注意我说尝试 - 在形成规范路径时,VM可以抛出一个IOException.这通常是因为它正在执行某些文件系统操作,其中任何一个都可能失败.