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

Dav*_*e B 18 java apache-commons-io

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

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);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

$ mkdir -p foo/bar/baz; touch foo/one_file
$ java -classpath commons-io-1.4.jar:. TestListFiles
Found file: foo/one_file
Run Code Online (Sandbox Code Playgroud)

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

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

DOS*_*DOS 20

一个旧的答案,但这对我有用:

FileUtils.listFilesAndDirs(new File(dir), TrueFileFilter.INSTANCE, DirectoryFileFilter.DIRECTORY);
Run Code Online (Sandbox Code Playgroud)

显示两者:

我用:

FileUtils.listFilesAndDirs(new File(dir), new NotFileFilter(TrueFileFilter.INSTANCE), DirectoryFileFilter.DIRECTORY)
Run Code Online (Sandbox Code Playgroud)

只显示目录而不显示文件......


Edd*_*die 6

如果您查看源代码并在JavaDoc中的行之间进行读取,您会发现 - 遗憾的是 - 此API并非旨在满足您的需求.它会返回一个列表文件(不列表文件和目录)符合所提供的论据.在源代码中 - 查看方法innerListFiles- 您将看到搜索目录而不是添加到结果列表中.

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

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

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

  • 我会做出同样的假设 - 直到它不起作用.他们真的应该让他们的JavaDoc更明确地说清楚. (5认同)

Jhe*_*ico 6

我在大多数非平凡的应用程序中都避免使用Java IO库,而是更喜欢使用Commons VFS.我相信用适当的参数调用这个方法可以实现你的目标,但我会给它一个很长的路要走.

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

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

        public boolean traverseDescendents(FileSelectInfo fileInfo) {
            return true;
        }
    });
Run Code Online (Sandbox Code Playgroud)

其中fileObject是FileObject的一个实例.


小智 6

你试过简单:

File rootFolder = new File(...);
File[] folders = rootFolder.listFiles((FileFilter) FileFilterUtils.directoryFileFilter());
Run Code Online (Sandbox Code Playgroud)

它似乎对我有用.当然,你需要递归.

希望能帮助到你.


adr*_*rau 0

根据他们的 API,它应该可以工作。

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