2016-08-02 44 views
3

给定两条路径,如何计算从一个到另一个的相对路径?在Java中查找从一个URL到另一个URL的相对路径

我想过用奇怪的方式使用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" 
+0

从'url1'到'url2'的相对路径不会是'./qux/quux/corge'就是'../ qux/quux/corge'。 –

+0

@JonnyHenly,你是对的。编辑我的帖子 – Brian

+0

相关:http://stackoverflow.com/a/705963/1831987 – VGR

回答

4

Java已经提供了这个功能,所以最安全的办法是去“标准”的方式:

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)和主机部分可以是不同的,那么转换url1和上面的,分成URL对象and using the getPath()方法,应该产生正确的相对路径。

+0

我测试了这个,为什么这段代码在索引4处显示'非法字符<:>? – SomeDude

+0

出于某种原因,我得到了'java.nio.file.InvalidPathException:非法字符<:>在索引4:http:// foo.com/bar/baz'。我正在使用'import java.nio.file。*;'。 – Brian

+0

@布莱恩,我发现你需要处理url1,url2删除'http:',然后'relativize'工作 – SomeDude

1

你可以做这样的事情:

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

这只有在您首先对URL进行规范化后才有效。 ['Path' API方法](http://stackoverflow.com/a/38728494/2071828)好得多。 –

+0

@BoristheSpider是的,我不知道它。 – Titus

1

不管你用什么哈克方法,它是将不得不遍历您的网址引擎盖下无论如何。 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); 
} 
+0

这只有在您首先对网址进行规范化后才有效。 ['Path' API方法](http://stackoverflow.com/a/38728494/2071828)好得多。 –

相关问题