[ https://issues.apache.org/jira/browse/IO-250?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17803978#comment-17803978 ]
Elliotte Rusty Harold commented on IO-250: ------------------------------------------ Interesting. Would be careful about testing and handling links. > Add FileUtils.pathTo(File aFile, File fromAnotherFile) > ------------------------------------------------------ > > Key: IO-250 > URL: https://issues.apache.org/jira/browse/IO-250 > Project: Commons IO > Issue Type: New Feature > Environment: n/a > Reporter: Jasper Blues > Priority: Minor > Fix For: 3.x > > Original Estimate: 3h > Remaining Estimate: 3h > > Please consider adding the following method to > org.apache.commons.io.FileUtils. I've submitted the method, with test cases > below (rather than create a patch file). As a single method, it should prove > very simple to integrate. > The method returns the path to a file, from another file, as described in the > Javadoc method header below: > {code} > /** > * Returns the path of a aFile relative to another aFile, for example the > location of a file: > * <code>resources/language/english/foobar.properties</code> relative to > * <code>resources/language/japanese/foobar.properties</code> is > * <code>../../english/foobar.properties</code> > * > * @param aFile the aFile to check relative location > * @param fromAnotherFile the base location > * @return the relative location path > * @throws java.io.IOException on IO error > */ > public static String pathTo(File aFile, File fromAnotherFile) throws > IOException { > LOGGER.debug("Find path to file: " + aFile.toString() + " from file: > " + fromAnotherFile.toString()); > Stack<File> fileToDirectories = directoriesFor(aFile); > Stack<File> fileFromDirectories = directoriesFor(fromAnotherFile); > while (fileToDirectories.peek().equals(fileFromDirectories.peek())) { > fileToDirectories.pop(); > fileFromDirectories.pop(); > if (fileToDirectories.isEmpty() || fileFromDirectories.isEmpty()) > { > break; > } > } > StringBuilder pathToCommonParentDirectory = new StringBuilder(); > while (!fileFromDirectories.isEmpty()) { > pathToCommonParentDirectory.append("../"); > fileFromDirectories.pop(); > } > StringBuilder pathToFileFromCommonParentDirectory = new > StringBuilder(); > while (!fileToDirectories.isEmpty()) { > > pathToFileFromCommonParentDirectory.append(fileToDirectories.pop().getName()); > if (!fileToDirectories.isEmpty()) { > pathToFileFromCommonParentDirectory.append("/"); > } > } > return pathToCommonParentDirectory.toString() + > pathToFileFromCommonParentDirectory.toString(); > } > private static Stack<File> directoriesFor(File file) throws IOException { > Stack<File> pathElements = new Stack<File>(); > for (File element = file.getCanonicalFile(); element != null; element > = element.getParentFile()) { > pathElements.push(element); > } > return pathElements; > } > {code} > . . . this is useful for batch processing, web applications, etc. > Test Cases: > {code} > @Test > public void pathTo() throws IOException { > //Setup > File file1 = new File("configs/js/en/a.xml"); > File file2 = new File("configs/js/ja/a.xml"); > Assert.assertNotNull(file1); > Assert.assertNotNull(file2); > //Test > Assert.assertEquals("../../en/a.xml", FileUtils.pathTo(file1, file2)); > } > @Test > public void pathTo_windowsStyleOnUnixMachine() throws IOException { > File file1 = new File("c:/fred/foobar/dude.properties"); > File file2 = new File("c:/data/zz.txt"); > Assert.assertEquals("../../fred/foobar/dude.properties", > FileUtils.pathTo(file1, file2)); > Assert.assertEquals("../../../data/zz.txt", FileUtils.pathTo(file2, > file1)); > } > @Test > public void pathTo_fromParentDirectory() throws IOException { > File file1 = new > File("ui-performance-enhancer/out/test/ui-performance-enhancer/configs/css/imported.xml"); > File file2 = new > File("ui-performance-enhancer/out/test/ui-performance-enhancer/configs/css"); > Assert.assertEquals("imported.xml", FileUtils.pathTo(file1, file2)); > } > {code} -- This message was sent by Atlassian Jira (v8.20.10#820010)