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

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

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

209262 次浏览

可以使用 档案类列出目录。

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. 在 JavaNIO.2中,您可以使用目录函数返回一个迭代器以支持更大的伸缩性。目录流类是一个对象,可用于迭代目录中的条目。

Given a starting directory as a String

  1. 创建一个以 String路径作为参数的方法:
  2. 根据起始目录创建一个新的 档案对象
  3. 使用 listFiles方法在工作目录中获取一个文件数组
  4. 在文件数组上循环
    1. 如果是文件,继续循环
    2. 如果是一个目录,则在这个新目录路径上打印出名称和 递归

@ Mohamed Mansour 你差点就到了... 你使用的“ dir”参数实际上是当前路径,所以它总是返回 true。为了查看子目录是否是子目录,您需要测试该子目录。

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));

如果您对使用 Java7和 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();
}

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

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();
}
});

下面是我的代码的解决方案。我只是稍微改变了一下 从第一个回答开始。这将逐行列出所需目录中的所有文件夹:

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!");
}

For those also interested in Java 7 and NIO, there is an alternative solution to @ voo’s answer above. We can use a 尝试使用资源 that calls Files.find() and a lambda function that is used to filter the directories.

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

对我有效的解决方案,在答案列表中缺失了。因此我在这里贴出这个解决方案:

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

这里我使用了 Apache commons-io-2.2.jar 中的 org.apache.commons.io.filefilter.FileFilterUtils

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

我想使用 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列表,那么您可以在收集之前添加一个 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
}

您可以使用 JAVA 7 Files 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());

If you want a specific value you can call map with the value you want before collecting the data.

    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);

这将逐字列出(即打印)所有子目录。它基本上是一种循环,在这种循环中,您不需要将项目存储到列表中。这是一个人最需要的东西,所以我把它留在这里。

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());
});