Java 如果源路径包含除真实文件夹以外的任何内容,则实际使用Path.relativize()

Java 如果源路径包含除真实文件夹以外的任何内容,则实际使用Path.relativize(),java,filesystems,java-7,nio,Java,Filesystems,Java 7,Nio,在准备Java7认证考试时,我必须开始仔细研究Path.relativize()方法。虽然从表面上看,它的目的似乎很简单,表示一条相对于另一条的路径,但我发现它的实现违背了我对文件系统的所有理解,即在Windows或Linux/Unix上。 考虑以下事项: // Case 1 System.out.println(Paths.get("c:\\folder1\\folder2").relativize(Paths.get("c:\\file.txt"))); // Case 2 System.

在准备Java7认证考试时,我必须开始仔细研究
Path.relativize()
方法。虽然从表面上看,它的目的似乎很简单,表示一条相对于另一条的路径,但我发现它的实现违背了我对文件系统的所有理解,即在Windows或Linux/Unix上。

考虑以下事项:

// Case 1
System.out.println(Paths.get("c:\\folder1\\folder2").relativize(Paths.get("c:\\file.txt")));

// Case 2
System.out.println(Paths.get("c:\\folder1\\folder2\\other-file.txt").relativize(Paths.get("c:\\file.txt")));

// Case 3
System.out.println(Paths.get("c:\\folder1\\..\\.\\folder1\\..\\.\\folder1\\..\\.\\folder1\\..").relativize(Paths.get("c:\\file.txt")));
我得到的结果是:

..\..\file.txt
..\..\..\file.txt
..\..\..\..\..\..\..\..\..\..\..\file.txt
案例1说明了该函数的直接用法,即在给定文件和文件夹的绝对路径的情况下,查找文件相对于文件夹的路径。很好,这样我就可以在Windows的cmd窗口中键入一些内容,并正确地找到我的文件。

如其他StackOverflow问题中所讨论的,案例2强调了一个事实,即该方法无法区分文件名和文件夹名(文件夹名中可以包含一个.,而文件名中可以没有)。好的,对我来说,这应该意味着该方法应该附带警告:“使用风险自负,如果提供一个叶子是文件的路径,那么相对化的结果在文件系统中将不起作用”。或者,如果是,是哪个文件系统?

案例3对我来说是胡说八道。该方法甚至没有考虑源路径中“.”和“.”的含义,而是在结果中愉快地使用“.”作为在源文件夹中提升级别的方式。这在我尚未遇到的理论文件系统中可能是有意义的,但在Windows、Linux或Unix中,结果是无法使用的。“..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\\..\\..\\..\\..\\\..\..\\..\\..\\..\\\..\..\\\..\..\\\\..\..\\\..\\

谢谢你到目前为止的支持。问题是:考虑到Path.relativize()方法的结果只在一小部分情况下具有现实意义,那么它有什么可能的用途呢?

您的表达式

Paths.get("c:\\folder1\\..\\.\\folder1\\..\\.\\folder1\\..\\.\\folder1\\..")
当标准化时,实际上只是
c:\

然后,如果将
c:\file.txt
与该路径相对化,则会得到一个相对路径,该路径将引导您到达该位置。从
c:\
,相对路径是
file.txt

结果

..\..\..\..\..\..\..\..\..\..\..\file.txt
完全等同于
file.txt
。规范化后,前导的
将被丢弃。我同意这并不漂亮,但这只是一个实现细节



谢谢你的回答。“正常化”这一点让我不知所措。如果我在Windows的cmd窗口中键入“dir c:\folder1\..\.\folder1\..\.\folder1\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\\..\..\\..\..\\..\\..\..\..\\..\..\..\\..\..\\..\..\\..\\..\..\。这就是为什么我质疑应用于实际路径的类似于文件系统的语法的目的,而实际路径在现实生活中不起作用。如果语法类似于{back-11}\\file.txt,那么我会得到它:它将是一种专有的方式来表示一个Java路径与另一个Java路径。但语法表明情况并非如此。这种规范化对什么有用?@NotSoOldNick
Path
有一个
normalize
方法。查看它以了解更多详细信息,如
。它基本上删除了冗余元素。显然,该路径不是目录,因此
dir
不起作用。但是,如果您试图复制它(或任何东西),它应该可以工作并找到
C:\file.txt
。谢谢,我终于得到了它!因此,为了获得文件系统可用的输出,在
relativize()
方法中作为源路径的路径应该首先得到规范化。@NotSoOldNick
relativize()
更适合人类可读的输出。我相信,如果您将它与任何执行实际文件系统IO的方法一起使用,它将通过Java或文件系统进行适当的转换。我不知道执行情况。