Як у Java я перелічу лише підкаталоги з каталогу?
Я хотів би скористатися функцією java.io.File, який найкращий метод у Java для цього?
Як у Java я перелічу лише підкаталоги з каталогу?
Я хотів би скористатися функцією java.io.File, який найкращий метод у Java для цього?
Відповіді:
Клас Файл можна використовувати для списку каталогів.
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));
Оновлення
Коментар автора до цього допису хотів швидшого шляху, великого обговорення тут: Як швидко отримати список каталогів на Яві?
В основному:
Дуже просте рішення 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();
}
});
::
в цьому випадку?
@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));
Якщо ви зацікавлені в рішенні, що використовує 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)
)
);
Для тих, хто також цікавиться Java 7 та NIO, є альтернативне рішення відповіді @ voo вище . Ми можемо використовувати пробні ресурси, що викликають, Files.find()
та лямбда-функцію, яка використовується для фільтрації каталогів.
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) {
...
}
Ми навіть можемо фільтрувати каталоги за назвою, змінюючи функцію лямбда:
(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
Я хотів би використовувати функцію 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
}
Files.list(Path)
що, ймовірно, те саме, що Files.walk(Path,1)
.
Files.list(Path)
, це справедлива альтернатива, якщо ми не хочемо повторювати рекурсивні папки. Ітератизувати папки рекурсивно, walk()
краще підходить.
Рішення, яке працювало на мене, відсутнє у списку відповідей. Тому я публікую це рішення тут:
File[]dirs = new File("/mypath/mydir/").listFiles((FileFilter)FileFilterUtils.directoryFileFilter());
Тут я використав org.apache.commons.io.filefilter.FileFilterUtils
з Apache commons-io-2.2.jar. Його документація доступна тут: https://commons.apache.org/proper/commons-io/javadocs/api-2.2/org/apache/commons/io/filefilter/FileFilterUtils.html
Дано початковий каталог як String
String
шлях як параметр. У способі:listFiles
методОсь рішення для мого коду. Я щойно змінив літле з першої відповіді . У цьому списку будуть вказані всі папки лише в потрібному каталозі по рядку:
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!");
}