Java中getPath()
,getAbsolutePath()
和getCanonicalPath()
之间有什么区别?
我什么时候使用每一个?
答案 0 :(得分:604)
考虑这些文件名:
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());
虽然两个路径都指向相同的位置,但输出将完全不同:
C:\Windows
C:\Windows\System32\drivers
答案 1 :(得分:125)
我发现的最好的方法是尝试这样的事情:
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) {}
}
}
您的输出将是:
test\..\.\file.txt
C:\projects\sandbox\trunk\test\..\.\file.txt
C:\projects\sandbox\trunk\file.txt
因此,getPath()
为您提供了基于File对象的路径,该路径可能是也可能不是相对的; getAbsolutePath()
为您提供文件的绝对路径;并且getCanonicalPath()
为您提供文件的唯一绝对路径。请注意,存在大量指向同一文件的绝对路径,但只有一条规范路径。
何时使用?取决于您要完成的任务,但如果您试图查看两个Files
是否指向磁盘上的同一文件,则可以比较它们的规范路径。只是一个例子。
答案 2 :(得分:63)
简而言之:
getPath()
获取构造File
对象的路径字符串,它可能是相对当前目录。getAbsolutePath()
在解析当前目录后获取路径字符串(如果它是相对的),从而产生完全限定的路径。getCanonicalPath()
在解析当前目录的任何相对路径后获取路径字符串,并删除任何相对路径(.
和..
),以及任何文件系统链接以返回路径文件系统认为规范意味着引用它指向的文件系统对象。此外,每个都有一个File等效项,它返回相应的File
对象。
答案 3 :(得分:35)
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"
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"
getCanonicalPath()
取决于系统。它将解析路径所代表的唯一位置。因此,如果路径中有任何“。”,则通常会删除它们。
何时使用它们。这取决于你想要达到的目标。 getPath()
对于可移植性非常有用。 getAbsolutePath()
对于查找文件系统位置很有用,getCanonicalPath()
对于检查两个文件是否相同特别有用。
答案 4 :(得分:19)
最重要的是,File
类试图表示Sun喜欢称之为“分层路径名”的视图(基本上是c:/foo.txt
或{{1}之类的路径})。这就是您根据路径创建文件的原因。您描述的操作都是对此“路径名”的操作。
/usr/muggins
获取使用(getPath()
)../foo.txt
获取创建文件的路径,但如果路径是相对的,则包含有关当前目录的信息(getAbsolutePath()
)/usr/bobstuff/../foo.txt
尝试获取文件绝对路径的唯一表示形式。这消除了“..”和“。”的间接方向。参考文献(getCanonicalPath()
)。注意我说尝试 - 在形成规范路径时,VM可以抛出/usr/foo.txt
。这通常是因为它正在执行某些文件系统操作,其中任何一个都可能失败。
答案 5 :(得分:3)
我发现我很少需要使用getCanonicalPath()
但是,如果在Windows上给出一个文件名为DOS 8.3格式的文件,例如java.io.tmpdir
系统属性返回,则此方法将返回“完整”文件名。