Uploaded image for project: 'Commons IO'
  1. Commons IO
  2. IO-250

Add FileUtils.pathTo(File aFile, File fromAnotherFile)

    XMLWordPrintableJSON

Details

    • New Feature
    • Status: Resolved
    • Minor
    • Resolution: Won't Do
    • None
    • 3.x
    • None
    • None
    • n/a

    Description

      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:

          /**
           * 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;
          }
      

      . . . this is useful for batch processing, web applications, etc.

      Test Cases:

           @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));
      
          }
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            jasperblues Jasper Blues
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - 3h
                3h
                Remaining:
                Remaining Estimate - 3h
                3h
                Logged:
                Time Spent - Not Specified
                Not Specified