// Derived from http://stackoverflow.com/a/3054692/250076 public static File getRelativeFile(File targetFile, File baseFile) { try { targetFile = targetFile.getCanonicalFile(); baseFile = baseFile.getCanonicalFile(); } catch (IOException ignored) { } String pathSeparator = File.separator; String basePath = baseFile.getAbsolutePath(); String normalizedTargetPath = normalize(targetFile.getAbsolutePath(), pathSeparator); String normalizedBasePath = normalize(basePath, pathSeparator); String[] base = normalizedBasePath.split(Pattern.quote(pathSeparator)); String[] target = normalizedTargetPath.split(Pattern.quote(pathSeparator)); StringBuilder common = new StringBuilder(); int commonIndex = 0; while (commonIndex < target.length && commonIndex < base.length && target[commonIndex].equals(base[commonIndex])) { common.append(target[commonIndex]).append(pathSeparator); commonIndex++; } if (commonIndex == 0) { throw new Error( "No common path element found for '" + normalizedTargetPath + "' and '" + normalizedBasePath + '\''); } boolean baseIsFile = true; if (baseFile.exists()) { baseIsFile = baseFile.isFile(); } else if (basePath.endsWith(pathSeparator)) { baseIsFile = false; } StringBuilder relative = new StringBuilder(); if (base.length != commonIndex) { int numDirsUp = baseIsFile ? base.length - commonIndex - 1 : base.length - commonIndex; for (int i = 0; i < numDirsUp; i++) { relative.append("..").append(pathSeparator); } } relative.append(normalizedTargetPath.substring(common.length())); return new File(relative.toString()); }