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

时间:2013-08-14 09:15:53

标签: java

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

我有两个File对象。

File dir;
File file;

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

dir  = /tmp/dir 
file = /tmp/dir/subdir1/subdir2/file.txt

我希望此检查返回true

现在我正在以这种方式进行检查:

String canonicalDir = dir.getCanonicalPath() + File.separator;
boolean subdir = file.getCanonicalPath().startsWith(canonicalDir);

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

有更好的方法吗?可能在某些图书馆?

由于

8 个答案:

答案 0 :(得分: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());
}

答案 1 :(得分:10)

除了来自rocketboy的asnwer之外,请使用getCanonicalPath()的{​​{1}}个instad,以便将getAbsolutePath()转换为\dir\dir2\..\file

\dir\file

    boolean areRelated = file.getCanonicalPath().contains(dir.getCanonicalPath() + File.separator);
    System.out.println(areRelated);

不要忘记使用boolean areRelated = child.getCanonicalPath().startsWith(parent.getCanonicalPath() + File.separator); 抓住任何Exception

注意:您可以使用try {...} catch {...}代替FileSystem.getSeparator()。正确的'这样做的方法是将您要检查的目录的File.separator作为getCanonicalPath()进行检查,然后检查是否以String结束,如果没有,则添加{{ 1}}到File.separator的末尾,以避免双斜线。这样,如果Java决定最后返回带斜杠的目录,或者你的目录字符串来自File.separator之外的其他地方,你就会跳过未来的奇怪行为。

注2:用于指向String问题的Thanx到@david。

答案 2 :(得分:5)

这种方法看起来非常可靠:

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

Source

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

答案 3 :(得分:0)

如果您计划使用文件和文件名,请检查apache fileutils和filenameutils库。充满了有用的(如果可移植性是必要的话,还有portale)函数

答案 4 :(得分:0)

public class Test {
public static void main(String[] args) {
    File root = new File("c:\\test");
    String fileName = "a.txt";
    try {
        boolean recursive = true;

        Collection files = FileUtils.listFiles(root, null, recursive);

        for (Iterator iterator = files.iterator(); iterator.hasNext();) {
            File file = (File) iterator.next();
            if (file.getName().equals(fileName))
                System.out.println(file.getAbsolutePath());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

答案 5 :(得分:0)

您可以从特定的DIR开始遍历文件树。 在Java 7中,有Files.walkFileTree方法。你只需要写自己的访客 检查当前节点是否是搜索文件。更多文档: http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#walkFileTree%28java.nio.file.Path,%20java.util.Set,%20int,%20java.nio.file.FileVisitor%29

答案 6 :(得分:0)

您可以执行此操作,但是并不能捕获所有用例,例如dir = / somedir /../ tmp / dir / etc ...,除非这也是文件的定义方式。

import java.nio.file.Path;
import java.nio.file.Paths;

public class FileTest {
    public static void main(final String... args) {
        final Path dir = Paths.get("/tmp/dir").toAbsolutePath();
        final Path file = Paths.get("/tmp/dir/subdir1/subdir2/file.txt").toAbsolutePath();
        System.out.println("Dir: " + dir);
        System.out.println("File: " + file);
        final boolean valid = file.startsWith(dir);
        System.out.println("Valid: " + valid);
    }
}

为了使检查正常进行,您确实需要使用toRealPath()或在您的示例中使用getCanonicalPath()进行映射,但是随后您必须处理这些示例的异常,这是绝对正确的你应该这样做。

答案 7 :(得分:-1)

如何比较路径?

    boolean areRelated = file.getAbsolutePath().contains(dir.getAbsolutePath());
    System.out.println(areRelated);

boolean areRelated = child.getAbsolutePath().startsWith(parent.getAbsolutePath())