Find the relative path between two files. @param base The base file. @param relative The file to be made relative. @return relative path
(File base, File relative)
| 39 | * @return relative path |
| 40 | */ |
| 41 | public static String findRelativePath(File base, File relative) |
| 42 | { |
| 43 | File testFile; |
| 44 | File relativeCanon; |
| 45 | try |
| 46 | { |
| 47 | testFile = base.getCanonicalFile(); |
| 48 | relativeCanon = relative.getCanonicalFile(); |
| 49 | } |
| 50 | catch (IOException e) |
| 51 | { |
| 52 | // The file can't be worked with so return it as is. |
| 53 | return relative.getAbsolutePath(); |
| 54 | } |
| 55 | if (!testFile.isDirectory()) |
| 56 | { |
| 57 | testFile = testFile.getParentFile(); |
| 58 | } |
| 59 | |
| 60 | // Cope with files on different drives in Windows. |
| 61 | if (!testFile.toPath().getRoot().equals(relativeCanon.toPath().getRoot())) |
| 62 | { |
| 63 | return relativeCanon.getAbsolutePath(); |
| 64 | } |
| 65 | |
| 66 | String relativePath = stripOffRoot(relativeCanon); |
| 67 | |
| 68 | StringBuilder dots = new StringBuilder(); |
| 69 | |
| 70 | do |
| 71 | { |
| 72 | if (testFile.getParentFile() == null) |
| 73 | { |
| 74 | //we're at the root... |
| 75 | return dots.append(relativePath).toString(); |
| 76 | } |
| 77 | |
| 78 | String testPath = stripOffRoot(testFile); |
| 79 | |
| 80 | if (relativePath.indexOf(testPath) == 0) |
| 81 | { |
| 82 | if (testPath.length() >= relativePath.length()) |
| 83 | { |
| 84 | Logging.log(Logging.WARNING, |
| 85 | "Unable to get path for " + relative + " relative to " + base + ". Using absolute path."); |
| 86 | return relative.getAbsolutePath(); |
| 87 | } |
| 88 | String pieceToKeep = relativePath.substring(testPath.length() + 1); |
| 89 | |
| 90 | return dots.append(pieceToKeep).toString(); |
| 91 | } |
| 92 | dots.append("..").append(File.separator); |
| 93 | |
| 94 | testFile = testFile.getParentFile(); |
| 95 | } |
| 96 | while (testFile != null); |
| 97 | |
| 98 | return dots + relativePath; |