[英]Java, List only subdirectories from a directory, not files
In Java, How do I list only subdirectories from a directory?在 Java 中,如何仅列出目录中的子目录?
I'd like to use the java.io.File functionality, what is the best method in Java for doing this?我想使用 java.io.File 功能,Java 中执行此操作的最佳方法是什么?
You can use the File class to list the directories.您可以使用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));
Update更新
Comment from the author on this post wanted a faster way, great discussion here: How to retrieve a list of directories QUICKLY in Java?作者对这篇文章的评论想要一种更快的方法,这里有很好的讨论: 如何在 Java 中快速检索目录列表?
Basically:基本上:
A very simple Java 8 solution:一个非常简单的 Java 8 解决方案:
File[] directories = new File("/your/path/").listFiles(File::isDirectory);
It's equivalent to using a FileFilter (works with older Java as well):它相当于使用 FileFilter(也适用于较旧的 Java):
File[] directories = new File("/your/path/").listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isDirectory();
}
});
@Mohamed Mansour you were almost there... the "dir" argument from that you were using is actually the curent path, so it will always return true. @Mohamed Mansour 你快到了......你使用的“dir”参数实际上是当前路径,所以它总是会返回true。 In order to see if the child is a subdirectory or not you need to test that child.
为了查看子目录是否为子目录,您需要测试该子目录。
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));
In case you're interested in a solution using Java 7 and NIO.2, it could go like this:如果您对使用 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();
}
ArrayList<File> directories = new ArrayList<File>(
Arrays.asList(
new File("your/path/").listFiles(File::isDirectory)
)
);
For those also interested in Java 7 and NIO, there is an alternative solution to @voo's answer above .对于那些也对 Java 7 和 NIO 感兴趣的人,上面@voo 的回答有一个替代解决方案。 We can use a try-with-resources that calls
Files.find()
and a lambda function that is used to filter the directories.我们可以使用调用
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) {
...
}
We can even filter directories by name by changing the lambda function:我们甚至可以通过更改 lambda 函数按名称过滤目录:
(path, attributes) -> attributes.isDirectory() && path.toString().contains("test")
or by date:或按日期:
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
I'd like to use the java.io.File functionality,
我想使用 java.io.File 功能,
In 2012 (date of the question) yes, not today. 2012 年(问题的日期)是的,不是今天。
java.nio
API has to be favored for such requirements. java.nio
API 必须满足这样的需求。
Terrible with so many answers, but not the simple way that I would use that is Files.walk().filter().collect()
.有这么多答案很糟糕,但不是我使用的简单方法
Files.walk().filter().collect()
。
Globally two approaches are possible :在全球范围内,可能有两种方法:
1) Files.walk(Path start, )
has no maxDepth
limitations while 1)
Files.walk(Path start, )
没有maxDepth
限制,而
2) Files.walk(Path start, int maxDepth, FileVisitOption... options)
allows to set it. 2)
Files.walk(Path start, int maxDepth, FileVisitOption... options)
允许设置它。
Without specifying any depth limitation, it would give :不指定任何深度限制,它将给出:
Path directory = Paths.get("/foo/bar");
try {
List<Path> directories =
Files.walk(directory)
.filter(Files::isDirectory)
.collect(Collectors.toList());
} catch (IOException e) {
// process exception
}
And if for legacy reasons, you need to get a List of File
you can just add a map(Path::toFile)
operation before the collect :如果由于遗留原因,您需要获取一个
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
}
The solution that worked for me, is missing from the list of answers.答案列表中缺少对我有用的解决方案。 Hence I am posting this solution here:
因此,我在这里发布此解决方案:
File[]dirs = new File("/mypath/mydir/").listFiles((FileFilter)FileFilterUtils.directoryFileFilter());
Here I have used org.apache.commons.io.filefilter.FileFilterUtils
from Apache commons-io-2.2.jar.这里我使用了 Apache commons-io-2.2.jar 中的
org.apache.commons.io.filefilter.FileFilterUtils
。 Its documentation is available here: https://commons.apache.org/proper/commons-io/javadocs/api-2.2/org/apache/commons/io/filefilter/FileFilterUtils.html其文档可在此处获得: https : //commons.apache.org/proper/commons-io/javadocs/api-2.2/org/apache/commons/io/filefilter/FileFilterUtils.html
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);
This will literally list (that is, print) all subdirectories.这将逐字列出(即打印)所有子目录。 It basically is a loop kind of where you don't need to store the items in between to a list.
它基本上是一种循环类型,您不需要将它们之间的项目存储到列表中。 This is what one most likely needs, so I leave it here.
这是一个人最可能需要的,所以我把它留在这里。
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());
});
Here is solution for my code.这是我的代码的解决方案。 I just did a litlle change from first answer .
我只是从第一个答案中做了一点改变。 This will list all folders only in desired directory line by line:
这将逐行列出所需目录中的所有文件夹:
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!");
}
Given a starting directory as a String
给定一个起始目录作为
String
String
path as the parameter.String
路径作为参数的方法。 In the method:listFiles
methodlistFiles
方法获取当前目录中的文件数组You can use the JAVA 7 Files api您可以使用 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.如果你想要一个特定的值,你可以在收集数据之前用你想要的值调用 map。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.