在 Java 中查找从一个 URL 到另一个的相对路径

Find relative path from one URL to another in Java

给定两条路径,如何计算从一条路径到另一条路径的相对路径?

我考虑过以奇特的方式使用 split,但它似乎有点老套,尤其是在 "http://foo.com/bar/baz#header""http://foo.com/bar/baz"?param=value 这样的情况下。

例如:

String url1 = "http://foo.com/bar/baz";
String url2 = "http://foo.com/bar/qux/quux/corge";

System.out.println(relative(url1, url2)); // -> "../qux/quux/corge"

你可以这样做:

public static String relative(String url1, String url2){
    String[] parts = url1.split("/");
    String similar = "";
    for(String part:parts){
        if(url2.contains(similar+part+"/")){
            similar+=part+"/";
        }
    }
    return "./"+url2.replace(similar, "");
}

无论您使用什么 hacky 方法,它都必须在引擎盖下循环遍历您的 URLs。 IndexOf()、split() 和其他查找字符的函数仍然具有 O(n) 运行时间,因为它们需要寻找这些字符。所以,您不妨编写自己的 "indexOf" 风格的小函数。只需比较每个字符,一次一个,直到发现差异。这标志着相同 URLs 的结束,并且由于我们可以偷偷摸摸地在循环外声明 'i',因此我们可以退出循环并保留该索引。然后你只需要吐出较长的剩余部分 URL!

public String relative (String url1, String url2) {
    int i;
    for(i = 0; i < url1.length(); i++) {
        if(url1.charAt(i) != url2.charAt(i))
            break;
    }
    if(url1.length() > url2.length())
        return url1.substring(i);
    return url2.substring(i);
}

Java 已经提供了这个功能,所以最安全的选择是 "standard" 方式:

String url1 = "http://foo.com/bar/baz";
String url2 = "http://foo.com/bar/qux/quux/corge";

Path p1 = Paths.get(url1);
Path p2 = Paths.get(url2);
Path p  = p1.relativize(p2);

System.out.println("Relative path: " + p);

上面的 print 语句显示了正确的相对路径 - 即,在本例中,

../qux/quux/corge

如果协议(例如,http 与 https)和主机部分可以不同,则将上面的 url1url2 转换为 URL 对象and using thegetPath ()` 方法,应该产生正确的相对路径。