使用FileUtils.listFiles以递归方式查找目录

时间:2009-05-23 01:50:12

标签: java apache-commons-io

我想收集目录下的所有文件列表,特别是包括子目录。我不喜欢自己做事,所以我在Apache Commons IO中使用FileUtils.listFiles。所以我有类似的东西:

import java.io.File;
import java.util.Collection;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;

public class TestListFiles {
  public static void main(String[] args) {
    Collection<File> found = FileUtils.listFiles(new File("foo"),
        TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
    for (File f : found) {
      System.out.println("Found file: " + f);
    }
  }
}

问题是,这似乎只能找到普通文件,而不是目录:

$ mkdir -p foo/bar/baz; touch foo/one_file
$ java -classpath commons-io-1.4.jar:. TestListFiles
Found file: foo/one_file

我已经将TrueFileFilter传递给了两个过滤器,所以我想不出任何更具包容性的东西。我希望它列出:"foo", "foo/one_file", "foo/bar", "foo/bar/baz"(按任意顺序)。

我也会接受非FileUtils解决方案,但是我必须编写自己的BFS,甚至从我所获得的列表中收集父目录集似乎很愚蠢。 (无论如何,这将错过空子目录。)这是在Linux,FWIW。

6 个答案:

答案 0 :(得分:19)

旧答案,但这对我有用:

FileUtils.listFilesAndDirs(new File(dir), TrueFileFilter.INSTANCE, DirectoryFileFilter.DIRECTORY);

显示两者:

我用:

FileUtils.listFilesAndDirs(new File(dir), new NotFileFilter(TrueFileFilter.INSTANCE), DirectoryFileFilter.DIRECTORY)

仅显示目录而非文件......

答案 1 :(得分:6)

如果您查看source code并阅读JavaDoc中的行,您会发现 - 遗憾的是 - 此API并非旨在满足您的需求。它将返回与提供的参数匹配的文件列表(不是文件和目录的列表)。在源代码中 - 查看方法innerListFiles - 您将看到搜索目录并且添加到结果列表中。

我不知道任何公共API会做你想要的。希望其他人知道一个。大多数可能是DFS,而不是BFS,这可能或可能不重要。 (到目前为止,所有 Java代码我曾经看过,目录树遍历是通过深度优先搜索完成的。这并不意味着BFS不在那里,当然。)

如果你真的想要一个给定目录下的所有列表,那么滚动你自己很容易。但我理解你不想重新发明轮子的愿望。

注意:Apache Commons Finder可能会支持您所需要的内容,但此库位于The Commons Sandbox中,这意味着它在此阶段更具实验性。它可能会也可能不会完整,可能会也可能不会维持。对于您正在寻找的东西,它也可能是重量级的。

答案 2 :(得分:6)

我在大多数非平凡的应用程序中都避免使用Java IO库,而是更喜欢使用Commons VFS。我相信使用适当的参数调用this method可以实现您的目标,但我会给它留下很长的路要走。[/ p>

具体来说,此代码将执行您想要的操作:

    FileObject[] files = fileObject.findFiles(new FileSelector() {
        public boolean includeFile(FileSelectInfo fileInfo)  {
            return fileInfo.getFile().getType() == FileType.FOLDER; }

        public boolean traverseDescendents(FileSelectInfo fileInfo) {
            return true;
        }
    });

其中fileObject是FileObject的一个实例。

答案 3 :(得分:6)

您是否尝试过简单:

File rootFolder = new File(...);
File[] folders = rootFolder.listFiles((FileFilter) FileFilterUtils.directoryFileFilter());

这似乎对我有用。 当然,你需要递归。

希望它有所帮助。

答案 4 :(得分:1)

更简单+完整的Commons VFS解决方案:

FileSystemManager fsManager = VFS.getManager();
FileObject fileObject = fsManager.resolveFile( "yourFileNameHere" );
FileObject[] files = fileObject.findFiles( new FileTypeSelector( FileType.FOLDER ) )

答案 5 :(得分:0)

它应该基于他们的API工作。

这是我自己的FileUtils版本,不像Commons IO那样完整,它只包含我需要的内容。搜索 findFiles 或者您可以使用 iterate 来避免创建大型列表(有时/大部分时间您只想对这些文件执行某些操作,以便在List中收集它们没有意义)。