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

在Java中查找从一个URL到另一个URL的相对路径,java,url,relative-path,Java,Url,Relative Path,给定两条路径,如何计算从一条路径到另一条路径的相对路径 我曾想过以奇特的方式使用split,但它似乎有点粗糙,尤其是在这样的情况下:”http://foo.com/bar/baz#header“或”http://foo.com/bar/baz“?参数=值 例如: String url1 = "http://foo.com/bar/baz"; String url2 = "http://foo.com/bar/qux/quux/corge"; System.out.println(relativ

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

我曾想过以奇特的方式使用
split
,但它似乎有点粗糙,尤其是在这样的情况下:
”http://foo.com/bar/baz#header“
”http://foo.com/bar/baz“?参数=值

例如:

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, "");
}

不管你使用什么黑客方法,它都必须在引擎盖下循环通过你的URL。IndexOf()、split()和其他查找字符的函数仍然有O(n)运行时,因为它们需要查找这些字符。因此,您也可以编写自己的小“indexOf”样式函数。只需逐一比较每个字符,直到找到差异。这标志着相同URL的结束,因为我们可以偷偷地在循环外声明“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);
}
相对公共字符串(字符串url1、字符串url2){
int i;
对于(i=0;iurl2.length())
返回url1.子字符串(i);
返回url2.子字符串(i);
}

Java
已经提供了此功能,因此最安全的选择是采用“标准”方式:

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

../qux/quux/corge

如果协议(例如http与https)和主机部分可能不同,则使用getPath()`方法将上面的
url1
url2
转换为
URL
对象
,应该产生正确的相对路径。

您从
url1
url2
的相对路径不会是
/qux/qux/corge
而是
。/qux/qux/corge
@JonnyHenly,您是对的。编辑我的postRelated:仅当您首先将URL正常化时,此选项才有效。更好的方法是,只有先对URL进行正常化,这才有效。更好。@BoristheSpider是的,我不知道。我测试了这一点,为什么这段代码在索引4显示
非法字符
?出于某种原因,我得到
java.nio.file.InvalidPathException:索引4显示非法字符:http://foo.com/bar/baz
。我正在使用
导入java.nio.file.*
@Brian,我发现您需要处理url1、url2以删除
http:
,然后
relatiize
工作我更改了
Path p1=Path.get(url1)
into
p1=path.get(新URL(url1.getPath())
和p2一样,它也能工作。@svasa,在我点击send之前,你一直在评论;)
../qux/quux/corge