Trong Java, Làm cách nào để liệt kê chỉ các thư mục con từ một thư mục?
Tôi muốn sử dụng chức năng java.io.File, phương pháp tốt nhất trong Java để thực hiện việc này là gì?
Trong Java, Làm cách nào để liệt kê chỉ các thư mục con từ một thư mục?
Tôi muốn sử dụng chức năng java.io.File, phương pháp tốt nhất trong Java để thực hiện việc này là gì?
Câu trả lời:
Bạn có thể sử dụng lớp Tệp để liệt kê các thư mục.
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));
Cập nhật
Nhận xét từ tác giả về bài đăng này muốn một cách nhanh hơn, thảo luận tuyệt vời ở đây: Làm thế nào để truy xuất danh sách thư mục NHANH CHÓNG trong Java?
Về cơ bản:
Một giải pháp Java 8 rất đơn giản:
File[] directories = new File("/your/path/").listFiles(File::isDirectory);
Nó tương đương với việc sử dụng FileFilter (cũng hoạt động với Java cũ hơn):
File[] directories = new File("/your/path/").listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isDirectory();
}
});
::
hoạt động như thế nào trong trường hợp này?
@Mohamed Mansour bạn gần như đã ở đó ... đối số "dir" mà bạn đang sử dụng thực sự là đường dẫn chữa bệnh, vì vậy nó sẽ luôn trả về true. Để xem con đó có phải là một thư mục con hay không, bạn cần phải kiểm tra con đó.
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));
Trong trường hợp bạn quan tâm đến một giải pháp sử dụng Java 7 và NIO.2, nó có thể như sau:
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)
)
);
Đối với những người quan tâm đến Java 7 và NIO, có một giải pháp thay thế cho câu trả lời của @ voo ở trên . Chúng ta có thể sử dụng try-with-resources để gọi Files.find()
và hàm lambda được sử dụng để lọc các thư mục.
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) {
...
}
Chúng tôi thậm chí có thể lọc các thư mục theo tên bằng cách thay đổi hàm lambda:
(path, attributes) -> attributes.isDirectory() && path.toString().contains("test")
hoặc theo ngày:
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
Tôi muốn sử dụng chức năng java.io.File,
Vào năm 2012 (ngày của câu hỏi) có, không phải ngày hôm nay. java.nio
API phải được ưu tiên cho các yêu cầu như vậy.
Kinh khủng với rất nhiều câu trả lời, nhưng không phải là cách đơn giản mà tôi sẽ sử dụng Files.walk().filter().collect()
.
Trên toàn cầu có thể có hai cách tiếp cận:
1) Files.walk(Path start, )
không có maxDepth
giới hạn trong khi
2) Files.walk(Path start, int maxDepth, FileVisitOption... options)
cho phép thiết lập nó.
Không chỉ định bất kỳ giới hạn độ sâu nào, nó sẽ cung cấp:
Path directory = Paths.get("/foo/bar");
try {
List<Path> directories =
Files.walk(directory)
.filter(Files::isDirectory)
.collect(Collectors.toList());
} catch (IOException e) {
// process exception
}
Và nếu vì lý do kế thừa, bạn cần có Danh sách File
bạn có thể thêm map(Path::toFile)
thao tác trước khi thu thập:
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
}
Files.list(Path)
mà có lẽ giống như Files.walk(Path,1)
.
Files.list(Path)
là một lựa chọn thay thế hợp lý nếu chúng ta không muốn lặp lại các thư mục một cách đệ quy. Để lặp lại các thư mục một cách đệ quy, walk()
phù hợp hơn.
Giải pháp làm việc cho tôi, bị thiếu trong danh sách các câu trả lời. Do đó tôi đăng giải pháp này ở đây:
File[]dirs = new File("/mypath/mydir/").listFiles((FileFilter)FileFilterUtils.directoryFileFilter());
Ở đây tôi đã sử dụng org.apache.commons.io.filefilter.FileFilterUtils
từ Apache commons-io-2.2.jar. Tài liệu của nó có sẵn tại đây: https://commons.apache.org/proper/commons-io/javadocs/api-2.2/org/apache/commons/io/filefilter/FileFilterUtils.html
Cho một thư mục bắt đầu dưới dạng String
String
đường dẫn làm tham số. Trong phương pháp:listFiles
phương phápĐây là giải pháp cho mã của tôi. Tôi vừa thực hiện một sự thay đổi nhỏ so với câu trả lời đầu tiên . Điều này sẽ liệt kê tất cả các thư mục chỉ trong từng dòng thư mục mong muốn:
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!");
}