将 nio 相对化应用于两个完全不同的/不相关的绝对路径有什么意义



我理解以下内容 - 这对我来说很有意义:

Path path3 = Paths.get("/partA/partB");
Path path4 = Paths.get("/partA/partC");

System.out.println(path3.relativize(path4));
System.out.println(path4.relativize(path3));

它打印

../部分C

../部分B

我知道 partB 和 partC 都有一个称为 partA 的公共父文件夹。因此,这两条路径在逻辑上可以相对化和../在上面的打印结果中,指的是这个常见的父文件夹。

但是当我对两个完全不相关的绝对路径执行相同的操作时,如下所示:

path3 = Paths.get("/xyz");
path4 = Paths.get("/folder/abc");

System.out.println("path3 is absolute - "+path3.isAbsolute()); 
System.out.println("path4 is absolute - "+path4.isAbsolute()); 
Path path3a = path3.relativize(path4);
System.out.println(path3a);
Path path4a = path4.relativize(path3);
System.out.println(path4a);

我得到以下结果:

路径 3 是绝对的 - 真

路径 4 是绝对的 - 真

../文件夹/ABC

../../xyz

这对我来说没有意义。我认为两个不相关的绝对路径可以相对化,假设它们代表本地网络中两台不同计算机的路径。

如果这种理解是正确的,那么为什么在第一种情况下我得到../(一个文件夹上层),但在其他情况下我得到../../(两个文件夹上部) - 如果它们都是网络中的绝对文件夹,它们不应该在网络级别有一个共同的父文件夹吗?也就是说,结果不应该是以下吗?:

../文件夹/ABC

../xyz

如果我的理解不正确,那么第二个相对化(具有不相关的绝对路径)背后的逻辑是什么?这一切在现实生活中的应用是什么?什么时候有用?

当我将其转换为绝对路径时,如下所示,我更加迷失:

Path path3b = path3a.toAbsolutePath();
Path path4b = path4a.toAbsolutePath();
Path path3c = path3b.normalize();
Path path4c = path4b.normalize();
System.out.println("path3a - "+path3a+" npath4a - "+path4a);
System.out.println("path3b - "+path3b+" npath4b - "+path4b);
System.out.println("path3c - "+path3c+" npath4c - "+path4c);

它打印:

路径3a - ../文件夹/ABC

路径4a - ../../xyz

path3b -/Users/myMac/NetBeansProjects/OCP/../文件夹/ABC

path4b -/Users/myMac/NetBeansProjects/OCP/../../xyz

path3c -/Users/myMac/NetBeansProjects/folder/abc

path4c -/Users/myMac/xyz

我完全迷失了,因为为什么两个绝对路径上的相对化路径被添加到我计算机中的当前路径中 - 它不应该转换回原始绝对路径吗?在理解这一切的纯逻辑和应用方面,我缺少什么?

(我了解代码的工作原理,我不了解当两条不相关的路径相对化时在现实生活中的逻辑和应用)

提前非常感谢。

如果你从/folder/abc开始,你想达到/xyz你必须上升两个级别,然后下降一个级别。上升两级意味着../..,下降一层意味着xyz。在一起就是../../xyz.

以下是使用/folder/abc的起始路径解析相对路径../../xyz时发生的情况。

/folder/abc + ..  == /folder/abc/.. == /folder
/folder     + ..  == /folder/..     == /
/           + xyz == /xyz

要计算从某个路径 A 到不相关路径 B 的相对路径,您必须首先通过将 A 中的目录数与..的目录数相加来达到顶层。这让你/.然后连接 B。

好的,@JohnKugelman提供的解释澄清了它(我接受了这个解释。在发布此消息时,我有 11 个声誉点,而对于投票,我需要 15 个代表点。因此,我现在不能对你的答案投赞成票。希望稍后再做)。

基本上,我误解的主要原因是假设相对化与路径中的顶级文件夹有关 - 这并非完全不合逻辑,因为一旦两条路径中的顶级文件夹被相对化(两条路径的顶级文件夹之间的映射是已知的),那么可以确定从路径一中的任何文件夹到路径二中的任何文件夹的路线图。但这种理解是不正确的。

现在我明白了,要正确理解相对化,需要记住两点:

1)事实证明,相对化与路径的底层有关(不是我想的顶级文件夹,所以在/folder/abc的情况下,Java构造了相对于abc的相对路径);

2)如fmbesteiro下面的回答所述,它的工作原理为FROM.relativize(TO);

因此,当我这样做时:

path3 = Paths.get("/xyz");
path4 = Paths.get("/folder/abc");        
System.out.println(path3.relativize(path4));
System.out.println(path4.relativize(path3));

并得到这个:

../文件夹/ABC

../../xyz

在第一种情况下(从路径 3 到 path4),正如 John Kugelman 所写,我必须上升一级,然后下降两级到文件夹,然后到 abc。在第二种情况下(从路径 4 到路径 3),我必须上升两级,然后下降一级到 xyz。

将相对化的绝对路径重新转换为 AbsolutePath() - 我知道它是毫无意义和毫无意义的,正如上面的评论中提到的@EJP(如果您正在使用绝对路径)。既然你已经使用绝对路径,你已经知道它,你为什么要使用 AbsolutePath() - 我尝试了它,因为我只是在试验它,并期望得到我曾经相对化的绝对路径。但是如果我得到别的东西,这不是问题,因为我已经知道绝对路径。

我还决定分享一些我用来理解相对化和规范化的代码 - 我希望它能帮助某人。

// prepared for Mac, needs to be changed for Windows 
import java.nio.file.Path;
import java.nio.file.Paths;
public class nio2test {
public static void main(String [] args) {
System.out.println(Paths.get("/aaaa/bbbb/cccc/./dddd").normalize());
//   /aaaa/bbbb/cccc/dddd
System.out.println(Paths.get("/aaaa/bbbb/cccc/../dddd").normalize());
//   /aaaa/bbbb/dddd
// note one dot
System.out.println(Paths.get("/aaaa/./bbbb/cccc/../dddd").normalize());
//   /aaaa/bbbb/dddd
System.out.println(Paths.get("/aaaa/bbbb/cccc/../../dddd").normalize());
//   /aaaa/dddd
// and so on
// Note the comma within get - operating system-dependent path.separator is automatically inserted between elements
System.out.println(Paths.get("/aaaa/.././bbbb","../cccc").normalize());
//    /cccc

System.out.println();
Path currentPath4Java = Paths.get(".");
System.out.println("currentPath4Java              - "+currentPath4Java);
System.out.println("currentPath4Java ( relative ) - "+currentPath4Java.toAbsolutePath());
System.out.println("currentPath4Java (normalised) - "+currentPath4Java.toAbsolutePath().normalize());
System.out.println("this is the location in relation to which Java constructs all relative paths");
}
}

当你使用相对化时,你实际上是在试图找出从你正在使用该方法的 Path 对象到你作为参数发送的路径的相对路径。基本上:

from.relativize(to)

如果 from 是/a/b/c并且 to 是/a/d/e则从/a/b/c/a/d/e的相对路径是../../d/e

因此,在您的情况下,从/xyz/folder/abc将需要它../folder/abc,而从/folder/abc/xyz的相反方式将需要相对路径../../xyz

关于规范化方法,请考虑..,就好像它们是访问的上一个文件夹一样,因此,对于使用的每个..,您必须返回一个文件夹。

最新更新