How to construct a relative path in Java from two absolute paths (or URLs)?

前端 未结 22 2643
小蘑菇
小蘑菇 2020-11-22 10:30

Given two absolute paths, e.g.

/var/data/stuff/xyz.dat
/var/data

How can one create a relative path that uses the second path as its base?

22条回答
  •  故里飘歌
    2020-11-22 10:57

    Actually my other answer didn't work if the target path wasn't a child of the base path.

    This should work.

    public class RelativePathFinder {
    
        public static String getRelativePath(String targetPath, String basePath, 
           String pathSeparator) {
    
            // find common path
            String[] target = targetPath.split(pathSeparator);
            String[] base = basePath.split(pathSeparator);
    
            String common = "";
            int commonIndex = 0;
            for (int i = 0; i < target.length && i < base.length; i++) {
    
                if (target[i].equals(base[i])) {
                    common += target[i] + pathSeparator;
                    commonIndex++;
                }
            }
    
    
            String relative = "";
            // is the target a child directory of the base directory?
            // i.e., target = /a/b/c/d, base = /a/b/
            if (commonIndex == base.length) {
                relative = "." + pathSeparator + targetPath.substring(common.length());
            }
            else {
                // determine how many directories we have to backtrack
                for (int i = 1; i <= commonIndex; i++) {
                    relative += ".." + pathSeparator;
                }
                relative += targetPath.substring(common.length());
            }
    
            return relative;
        }
    
        public static String getRelativePath(String targetPath, String basePath) {
            return getRelativePath(targetPath, basePath, File.pathSeparator);
        }
    }
    

    public class RelativePathFinderTest extends TestCase {
    
        public void testGetRelativePath() {
            assertEquals("./stuff/xyz.dat", RelativePathFinder.getRelativePath(
                    "/var/data/stuff/xyz.dat", "/var/data/", "/"));
            assertEquals("../../b/c", RelativePathFinder.getRelativePath("/a/b/c",
                    "/a/x/y/", "/"));
        }
    
    }
    

提交回复
热议问题