在Java中getPath(),getAbsolutePath()和getCanonicalPath()有什么区别?
在Java中getPath()
, getAbsolutePath()
和getCanonicalPath()
有什么getCanonicalPath()
?
我什么时候使用每一个?
考虑这些文件名:
C:\temp\file.txt
– 这是一个path,一个绝对path和一个规范path。
.\file.txt
– 这是一个path。 这既不是一条绝对的道路,也不是一条规范的道路。
C:\temp\myapp\bin\..\\..\file.txt
– 这是一个path和一个绝对path。 这不是一个规范的path。
规范的道路永远是一条绝对的道路。
从path转换到规范path使其成为绝对(通常在当前工作目录上,例如./file.txt
变为c:/temp/file.txt
)。 文件的规范path只是“净化”path,删除和解决像..\
和parsing符号链接(在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());
虽然两条path都指向相同的位置,但输出将会非常不同:
C:\Windows C:\Windows\System32\drivers
我发现最好的方法是尝试一下:
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对象的path,这个对象可能是也可能不是相对的; getAbsolutePath()
为您提供文件的绝对path; 和getCanonicalPath()
为您提供文件的唯一绝对path。 请注意,有相当多的绝对path指向同一个文件,但只有一个规范path。
何时使用每个? 取决于你想完成什么,但是如果你想看看两个Files
是否指向磁盘上的同一个文件,你可以比较它们的规范path。 只是一个例子。
简而言之:
-
getPath()
获取File
对象构造的pathstring,它可能是相对当前目录。 -
getAbsolutePath()
在相对于当前目录parsing之后获取pathstring,如果它是相对的,则得到完全限定的path。 -
getCanonicalPath()
在根据当前目录parsing任何相对path之后获取pathstring,并删除任何相对path(.
和..
),以及任何文件系统链接,以返回文件系统认为引用文件系统的规范方法的path它指向的对象。
而且,每个文件都有一个等价的文件,它返回相应的File
对象。
getPath()
返回用于创buildFile
对象的path。 这个返回值不会根据运行的位置而改变(下面的结果是针对窗口的,分隔符在其他地方明显不同)
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()
将根据执行位置或驱动器parsingpath。 所以如果从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()
是依赖于系统的。 它将parsingpath所代表的独特位置。 所以,如果你在path中有任何“。”,他们通常会被删除。
至于何时使用它们。 这取决于你想要达到的目标。 getPath()
对于可移植性很有用。 getAbsolutePath()
对于查找文件系统位置非常有用,而getCanonicalPath()
对于检查两个文件是否相同特别有用。
最让你头痛的是File
类试图代表Sun称之为“层级path名”(基本上是“c:/foo.txt”或/ usr / muggins“)的path。就是为什么用path创build文件的原因,你所描述的操作都是这个“path名”上的操作。
-
getPath()
获取文件的创buildpath(../foo.txt
) -
getAbsolutePath()
获取文件的创buildpath,但包含有关当前目录的信息(/usr/bobstuff/../foo.txt
) -
getCanonicalPath()
尝试获取文件绝对path的唯一表示。 这消除了“..”和“。”之间的间接性。 引用(/usr/foo.txt
)。
注意我说的尝试 – 在形成规范path,虚拟机可以抛出一个IOException
。 这通常是因为它正在执行一些文件系统操作,其中任何一个都可能失败。
我发现我很less需要使用getCanonicalPath()
但是,如果在Windows上为DOS 8.3格式的文件(例如java.io.tmpdir
系统属性返回getCanonicalPath()
指定了文件,则此方法将返回“完整”文件名。