How to check if a given path is possible child of another path?

后端 未结 9 946
不思量自难忘°
不思量自难忘° 2020-12-09 01:53

I am trying to find if given path is possible child of another path using java. Both path may not exist.

Say c:\\Program Files\\My Company\\test\\My App

相关标签:
9条回答
  • 2020-12-09 02:00
    File parent = maybeChild.getParentFile();
    while ( parent != null ) {
      if ( parent.equals( possibleParent ) )
        return true;
      parent = parent.getParentFile();
    }
    return false;
    
    0 讨论(0)
  • 2020-12-09 02:01
    maybeChild.getCanonicalPath().startsWith( possibleParent.getCanonicalPath() );
    
    0 讨论(0)
  • 2020-12-09 02:03

    Asides from the fact the paths may not exist (and the canonicalisation may not succeed), this looks like a reasonable approach that should work in the straightforward case.

    You may want to look at calling getParentFile() on the "maybe child" in a loop, testing if it matches the parent at each step. You can also short-circuit the comparison if the parent isn't a (real) directory.

    Perhaps something like the following:

    boolean myCheck(File maybeChild, File possibleParent) throws IOException
    {
        final File parent = possibleParent.getCanonicalFile();
        if (!parent.exists() || !parent.isDirectory()) {
            // this cannot possibly be the parent
            return false;
        }
    
        File child = maybeChild.getCanonicalFile();
        while (child != null) {
            if (child.equals(parent)) {
                return true;
            }
            child = child.getParentFile();
        }
        // No match found, and we've hit the root directory
        return false;
    }
    

    Note that if you want the child relationship to be strict (i.e. a directory is not a child of itself) you can change the initial child assignment on line 9 to be child.getParentFile() so the first check happens on the child's containing directory.

    0 讨论(0)
  • 2020-12-09 02:05

    That will probably work fine as it is, although I would use getCanonicalPath() rather than getAbsolutePath(). This should normalize any weird paths like x/../y/z which would otherwise screw up the matching.

    0 讨论(0)
  • 2020-12-09 02:07

    Old question but a pre-1.7 solution:

    public boolean startsWith(String possibleRoot, String possibleChildOrSame) {
            String[] possiblePath = new File(possibleRoot).getAbsolutePath().replace('\\', '/').split("/");
            String[] possibleChildOrSamePath = new File(possibleChildOrSame).getAbsolutePath().replace('\\', '/').split("/");
    
            if (possibleChildOrSamePath.length < possiblePath.length) {
                return false;
            }
    
            // not ignoring case
            for (int i = 0; i < possiblePath.length; i++) {
                if (!possiblePath[i].equals(possibleChildOrSamePath[i])) {
                    return false;
                }
            }
            return true;
    }
    

    For completeness the java 1.7+ solution:

    public boolean startsWith(String possibleRoot, String possibleChildOrSame) {
            Path p1 = Paths.get(possibleChildOrSame).toAbsolutePath();
            Path p2 = Paths.get(possibleRoot).toAbsolutePath();
            return p1.startsWith(p2);
    }
    
    0 讨论(0)
  • 2020-12-09 02:09

    Surprisingly there is no simple, yet functional solution.

    The accepted answer does consider same directories as child, which is wrong.

    Here is one using java.nio.file.Path API only:

    static boolean isChildPath(Path parent, Path child){
          Path pn = parent.normalize();
          Path cn = child.normalize();
          return cn.getNameCount() > pn.getNameCount() && cn.startsWith(pn);
    }
    

    Test cases:

     @Test
    public void testChildPath() {
          assertThat(isChildPath(Paths.get("/FolderA/FolderB/F"), Paths.get("/FolderA/FolderB/F"))).isFalse();
          assertThat(isChildPath(Paths.get("/FolderA/FolderB/F"), Paths.get("/FolderA/FolderB/F/A"))).isTrue();
          assertThat(isChildPath(Paths.get("/FolderA/FolderB/F"), Paths.get("/FolderA/FolderB/F/A.txt"))).isTrue();
    
          assertThat(isChildPath(Paths.get("/FolderA/FolderB/F"), Paths.get("/FolderA/FolderB/F/../A"))).isFalse();
          assertThat(isChildPath(Paths.get("/FolderA/FolderB/F"), Paths.get("/FolderA/FolderB/FA"))).isFalse();
    
          assertThat(isChildPath(Paths.get("FolderA"), Paths.get("FolderA"))).isFalse();
          assertThat(isChildPath(Paths.get("FolderA"), Paths.get("FolderA/B"))).isTrue();
          assertThat(isChildPath(Paths.get("FolderA"), Paths.get("FolderA/B"))).isTrue();
          assertThat(isChildPath(Paths.get("FolderA"), Paths.get("FolderAB"))).isFalse();
          assertThat(isChildPath(Paths.get("/FolderA/FolderB/F"), Paths.get("/FolderA/FolderB/F/Z/X/../A"))).isTrue();
    }
    
    0 讨论(0)
提交回复
热议问题