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

前端 未结 22 2788
小蘑菇
小蘑菇 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 11:05

    Passes Dónal's tests, the only change - if no common root it returns target path (it could be already relative)

    import static java.util.Arrays.asList;
    import static java.util.Collections.nCopies;
    import static org.apache.commons.io.FilenameUtils.normalizeNoEndSeparator;
    import static org.apache.commons.io.FilenameUtils.separatorsToUnix;
    import static org.apache.commons.lang3.StringUtils.getCommonPrefix;
    import static org.apache.commons.lang3.StringUtils.isBlank;
    import static org.apache.commons.lang3.StringUtils.isNotEmpty;
    import static org.apache.commons.lang3.StringUtils.join;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    public class ResourceUtils {
    
        public static String getRelativePath(String targetPath, String basePath, String pathSeparator) {
            File baseFile = new File(basePath);
            if (baseFile.isFile() || !baseFile.exists() && !basePath.endsWith("/") && !basePath.endsWith("\\"))
                basePath = baseFile.getParent();
    
            String target = separatorsToUnix(normalizeNoEndSeparator(targetPath));
            String base = separatorsToUnix(normalizeNoEndSeparator(basePath));
    
            String commonPrefix = getCommonPrefix(target, base);
            if (isBlank(commonPrefix))
                return targetPath.replaceAll("/", pathSeparator);
    
            target = target.replaceFirst(commonPrefix, "");
            base = base.replaceFirst(commonPrefix, "");
    
            List result = new ArrayList<>();
            if (isNotEmpty(base))
                result.addAll(nCopies(base.split("/").length, ".."));
            result.addAll(asList(target.replaceFirst("^/", "").split("/")));
    
            return join(result, pathSeparator);
        }
    }
    

提交回复
热议问题