Answers:
考虑以下文件名:
C:\temp\file.txt
-这是一条路径,一条绝对路径和一条规范路径。
.\file.txt
-这是一条路。它既不是绝对路径也不是规范路径。
C:\temp\myapp\bin\..\\..\file.txt
-这是一条路径,也是一条绝对路径。这不是一条规范的道路。
规范路径始终是绝对路径。
从路径转换为规范路径使其成为绝对路径(通常添加到当前工作目录,因此例如./file.txt
成为c:/temp/file.txt
)。文件的规范路径仅“净化”路径,删除..\
并解决符号链接之类的问题并解决(在Unix上)符号链接。
还要注意以下带有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
C:\temp\file.txt
的规范路径-临时目录可能是文件系统软链接或硬链接(NTFS中的连接),而file.txt可能是软链接。我不知道文件系统是否可以区分文件的硬链接。
getAbsolutePath()
而不是的原因getCanonicalPath()
。甚至看起来更好,因为规范的../
部分会自动解析这些部分。
getCanonicalPath
抛出IOException
虽然getAbsolutePath
没有,如果这是一个考虑因素。
我发现对这种事情有感觉的最好方法是尝试一下:
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
文件是否指向磁盘上的同一文件,则可以比较它们的规范路径。只是一个例子。
but if you were trying to see if two Files are pointing at the same file on disk
怎么样?请举个例子吗?
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()
非常有用,对于检查两个文件是否相同特别有用。
getCanonicalPath() is particularly useful to check if two files are the same.
直截了当的是,File
该类试图代表Sun所称的“分层路径名”(基本上是类似c:/foo.txt
or 的路径/usr/muggins
)的视图。这就是为什么要根据路径创建文件的原因。您描述的操作都是针对此“路径名”的所有操作。
getPath()
获取使用(../foo.txt
)创建文件的路径getAbsolutePath()
获取创建文件的路径,但如果路径是相对的(/usr/bobstuff/../foo.txt
),则包含有关当前目录的信息getCanonicalPath()
尝试获取文件绝对路径的唯一表示形式。这消除了“ ..”和“。”的间接访问。参考(/usr/foo.txt
)。请注意,我说的是尝试 -在形成规范路径时,VM可以抛出IOException
。这通常是因为它正在执行某些文件系统操作,而其中任何一个操作都可能失败。
Path.toAbsolutePath().normalize()
哪一个是介于规范(真实)路径和绝对路径之间的良好中间地带。