Java,仅列出目录中的子目录,而不是文件

时间:2011-02-26 05:23:08

标签: java file

在Java中,如何仅列出目录中的子目录?

我想使用java.io.File功能,Java中最好的方法是什么?

13 个答案:

答案 0 :(得分:121)

您可以使用File类列出目录。

File file = new File("/path/to/directory");
String[] directories = file.list(new FilenameFilter() {
  @Override
  public boolean accept(File current, String name) {
    return new File(current, name).isDirectory();
  }
});
System.out.println(Arrays.toString(directories));

<强>更新

作者对这篇文章的评论想要一个更快的方式,这里有很好的讨论: How to retrieve a list of directories QUICKLY in Java?

基本上:

  1. 如果您控制文件结构,我会尽量避免陷入这种情况。
  2. 在Java NIO.2中,您可以使用目录函数返回迭代器以允许更大的缩放。目录流类是一个对象,可用于迭代目录中的条目。

答案 1 :(得分:91)

一个非常简单的Java 8解决方案:

File[] directories = new File("/your/path/").listFiles(File::isDirectory);

它等同于使用FileFilter(也适用于旧Java):

File[] directories = new File("/your/path/").listFiles(new FileFilter() {
    @Override
    public boolean accept(File file) {
        return file.isDirectory();
    }
});

答案 2 :(得分:13)

@Mohamed Mansour你几乎就在那里......你正在使用的“dir”论证实际上是一条前沿路径,所以它总是会回归真实。为了查看孩子是否是子目录,您需要测试该孩子。

File file = new File("/path/to/directory");
String[] directories = file.list(new FilenameFilter() {
  @Override
  public boolean accept(File current, String name) {
    return new File(current, name).isDirectory();
  }
});
System.out.println(Arrays.toString(directories));

答案 3 :(得分:7)

如果您对使用Java 7和NIO.2的解决方案感兴趣,可以这样:

private static class DirectoriesFilter implements Filter<Path> {
    @Override
    public boolean accept(Path entry) throws IOException {
        return Files.isDirectory(entry);
    }
}

try (DirectoryStream<Path> ds = Files.newDirectoryStream(FileSystems.getDefault().getPath(root), new DirectoriesFilter())) {
        for (Path p : ds) {
            System.out.println(p.getFileName());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

答案 4 :(得分:1)

对于那些也对Java 7和NIO感兴趣的人,有@voo's answer above的替代解决方案。我们可以使用调用Files.find() try-with-resources 和用于过滤目录的lambda函数。

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;


final Path directory = Paths.get("/path/to/folder");

try (Stream<Path> paths = Files.find(directory, Integer.MAX_VALUE, (path, attributes) -> attributes.isDirectory())) {
    paths.forEach(System.out::println);
} catch (IOException e) {
    ...
}

我们甚至可以通过更改lambda函数来按名称过滤目录:

(path, attributes) -> attributes.isDirectory() && path.toString().contains("test")

或按日期:

final long now = System.currentTimeMillis();
final long yesterday = new Date(now - 24 * 60 * 60 * 1000L).getTime();

// modified in the last 24 hours
(path, attributes) -> attributes.isDirectory() && attributes.lastModifiedTime().toMillis() > yesterday

答案 5 :(得分:1)

ArrayList<File> directories = new ArrayList<File>(
    Arrays.asList(
        new File("your/path/").listFiles(File::isDirectory)
    )
);

答案 6 :(得分:0)

将起始目录指定为String

  1. 创建一个以String路径为参数的方法。在方法中:
  2. 根据起始目录
  3. 创建一个新的File对象
  4. 使用listFiles方法
  5. 获取当前目录中的文件数组
  6. 循环遍历文件数组
    1. 如果是文件,请继续循环
    2. 如果是目录,请在此新目录路径上打印出名称​​ recurse

答案 7 :(得分:0)

这是我的代码的解决方案。我刚刚进行了一次改变from first answer。这将逐行列出所需文件夹中的所有文件夹:

try {
            File file = new File("D:\\admir\\MyBookLibrary");
            String[] directories = file.list(new FilenameFilter() {
              @Override
              public boolean accept(File current, String name) {
                return new File(current, name).isDirectory();
              }
            });
            for(int i = 0;i < directories.length;i++) {
                if(directories[i] != null) {
                    System.out.println(Arrays.asList(directories[i]));

                }
            }
        }catch(Exception e) {
            System.err.println("Error!");
        }

答案 8 :(得分:0)

答案列表中缺少对我有用的解决方案。因此,我在这里发布了此解决方案:

File[]dirs = new File("/mypath/mydir/").listFiles((FileFilter)FileFilterUtils.directoryFileFilter());

在这里,我使用了来自Apache commons-io-2.2.jar的org.apache.commons.io.filefilter.FileFilterUtils。其文档可在以下位置找到:https://commons.apache.org/proper/commons-io/javadocs/api-2.2/org/apache/commons/io/filefilter/FileFilterUtils.html

答案 9 :(得分:0)

  

我想使用java.io.File功能,

2012年(问题的日期)是的,不是今天。 java.nio API必须满足此类要求。

这么多答案很糟糕,但是我使用的简单方法不是Files.walk().filter().collect()

在全球范围内,两种方法都是可行的:

1)Files.walk(Path start, )没有maxDepth限制,而

2)Files.walk(Path start, int maxDepth, FileVisitOption... options)可以进行设置。

不指定任何深度限制,它将给出:

Path directory = Paths.get("/foo/bar");

try {
    List<Path> directories =
            Files.walk(directory)
                 .filter(Files::isDirectory)
                 .collect(Collectors.toList());
} catch (IOException e) {
    // process exception
}

如果由于遗留原因,您需要获取File的列表,您可以在collect之前添加一个map(Path::toFile)操作:

Path directory = Paths.get("/foo/bar");

try {
    List<File> directories =
            Files.walk(directory)
                 .filter(Files::isDirectory)
                 .map(Path::toFile)
                 .collect(Collectors.toList());
} catch (IOException e) {
    // process exception
}

答案 10 :(得分:0)

您可以使用JAVA 7文件api

Path myDirectoryPath = Paths.get("path to my directory");
List<Path> subDirectories = Files.find(
                    myDirectoryPath ,
                    Integer.MAX_VALUE,
                    (filePath, fileAttr) -> fileAttr.isDirectory() && !filePath.equals(myDirectoryPath )
            ).collect(Collectors.toList());

如果需要特定值,可以在收集数据之前使用所需值调用map。

答案 11 :(得分:0)

    File files = new File("src");
    // src is folder name...
    //This will return the list of the subDirectories
    List<File> subDirectories = Arrays.stream(files.listFiles()).filter(File::isDirectory).collect(Collectors.toList());
// this will print all the sub directories
Arrays.stream(files.listFiles()).filter(File::isDirectory).forEach(System.out::println);

答案 12 :(得分:0)

这将逐字列出(即打印)所有子目录。从本质上讲,这是一种循环,您无需在列表之间存储项目。这是最可能需要的,所以我留在这里。

Path directory = Paths.get("D:\\directory\\to\\list");

Files.walk(directory, 1).filter(entry -> !entry.equals(directory))
    .filter(Files::isDirectory).forEach(subdirectory ->
{
    // do whatever you want with the subdirectories
    System.out.println(subdirectory.getFileName());
});