检查文件是否在(子)目录中

Joh*_*orn 10 java

我想检查现有文件是在特定目录中还是在其子目录中.

我有两个File对象.

File dir;
File file;
Run Code Online (Sandbox Code Playgroud)

两者都保证存在.我们假设

dir  = /tmp/dir 
file = /tmp/dir/subdir1/subdir2/file.txt
Run Code Online (Sandbox Code Playgroud)

我希望此检查返回true

现在我正在这样检查:

String canonicalDir = dir.getCanonicalPath() + File.separator;
boolean subdir = file.getCanonicalPath().startsWith(canonicalDir);
Run Code Online (Sandbox Code Playgroud)

这似乎适用于我的有限测试,但我不确定这是否会在某些操作系统上出现问题.我也不喜欢getCanonicalPath()可以抛出我必须处理的IOException.

有没有更好的办法?可能在某些图书馆?

谢谢

Jor*_*lez 11

除了从孟阳的asnwer,使用getCanonicalPath()的instad getAbsolutePath()从而\dir\dir2\..\file被转换为\dir\file:

    boolean areRelated = file.getCanonicalPath().contains(dir.getCanonicalPath() + File.separator);
    System.out.println(areRelated);
Run Code Online (Sandbox Code Playgroud)

要么

boolean areRelated = child.getCanonicalPath().startsWith(parent.getCanonicalPath() + File.separator);
Run Code Online (Sandbox Code Playgroud)

不要忘了捕捉任何Exceptiontry {...} catch {...}.

注意:您可以使用FileSystem.getSeparator()而不是File.separator.执行此操作的"正确"方法getCanonicalPath()是将要检查的目录作为a String,然后检查是否以a结尾,File.separator如果不是则添加File.separator到结尾String,以避免双斜线.这样,如果Java决定在最后返回带有斜杠的目录,或者如果您的目录字符串来自其他地方,则可以跳过将来的奇怪行为Java.io.File.

注2:用于指出File.separator问题的Thanx到@david .


dac*_*cwe 10

我会创建一个小实用程序方法:

public static boolean isInSubDirectory(File dir, File file) {

    if (file == null)
        return false;

    if (file.equals(dir))
        return true;

    return isInSubDirectory(dir, file.getParentFile());
}
Run Code Online (Sandbox Code Playgroud)

  • 我会首先检查文件是否实际上是一个文件.它可能不会[找到父母](http://stackoverflow.com/questions/11296949/created-file-has-no-parent).这听起来是个好主意,但应该是更大解决方案的一部分. (2认同)

tsa*_*ein 6

这个方法看起来很稳固:

/**
 * Checks, whether the child directory is a subdirectory of the base 
 * directory.
 *
 * @param base the base directory.
 * @param child the suspected child directory.
 * @return true, if the child is a subdirectory of the base directory.
 * @throws IOException if an IOError occured during the test.
 */
public boolean isSubDirectory(File base, File child)
    throws IOException {
    base = base.getCanonicalFile();
    child = child.getCanonicalFile();

    File parentFile = child;
    while (parentFile != null) {
        if (base.equals(parentFile)) {
            return true;
        }
        parentFile = parentFile.getParentFile();
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

资源

它与dacwe的解决方案类似,但不使用递归(尽管在这种情况下不应该有很大的不同).


roc*_*boy -1

比较路径怎么样?

    boolean areRelated = file.getAbsolutePath().contains(dir.getAbsolutePath());
    System.out.println(areRelated);
Run Code Online (Sandbox Code Playgroud)

或者

boolean areRelated = child.getAbsolutePath().startsWith(parent.getAbsolutePath())
Run Code Online (Sandbox Code Playgroud)

  • 对于包含“/tmp/something/../dir”之类的内容的路径可能会出现问题,这在我的应用程序中是可能的。 (2认同)
  • 您至少必须使用“getCanonicalFile()”! (2认同)