W Javie, jak wyświetlić tylko podkatalogi z katalogu?
Chciałbym skorzystać z funkcjonalności java.io.File. Jaka jest najlepsza metoda w Javie, aby to zrobić?
W Javie, jak wyświetlić tylko podkatalogi z katalogu?
Chciałbym skorzystać z funkcjonalności java.io.File. Jaka jest najlepsza metoda w Javie, aby to zrobić?
Odpowiedzi:
Możesz użyć klasy File, aby wyświetlić listę katalogów.
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));
Aktualizacja
Komentarz autora do tego postu chciał szybszego sposobu, świetna dyskusja tutaj: Jak szybko pobrać listę katalogów w Javie?
Gruntownie:
Bardzo proste rozwiązanie Java 8:
File[] directories = new File("/your/path/").listFiles(File::isDirectory);
Jest to równoważne użyciu FileFilter (działa również ze starszą Javą):
File[] directories = new File("/your/path/").listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isDirectory();
}
});
::w tym przypadku?
@Mohamed Mansour, prawie byłeś ... argument "dir", którego używałeś, jest w rzeczywistości aktualną ścieżką, więc zawsze zwróci prawdę. Aby sprawdzić, czy dziecko jest podkatalogiem, czy nie, musisz je przetestować.
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));
Jeśli jesteś zainteresowany rozwiązaniem wykorzystującym Javę 7 i NIO.2, może to wyglądać tak:
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)
)
);
Dla tych, którzy są również zainteresowani Javą 7 i NIO, istnieje alternatywne rozwiązanie powyższej odpowiedzi @ voo . Możemy użyć wywołania try-with-resourcesFiles.find() i funkcji lambda, która jest używana do filtrowania katalogów.
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) {
...
}
Możemy nawet filtrować katalogi według nazwy, zmieniając funkcję lambda:
(path, attributes) -> attributes.isDirectory() && path.toString().contains("test")
lub według daty:
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
Chciałbym skorzystać z funkcjonalności java.io.File,
W 2012 roku (data zapytania) tak, nie dzisiaj. java.nioW przypadku takich wymagań należy preferować API.
Okropne z tak wieloma odpowiedziami, ale nie w prosty sposób, w jaki bym tego użył Files.walk().filter().collect().
Globalnie możliwe są dwa podejścia:
1) Files.walk(Path start, )nie ma żadnych maxDepthograniczeń
2) Files.walk(Path start, int maxDepth, FileVisitOption... options)pozwala to ustawić.
Bez określenia ograniczeń głębokości dałoby:
Path directory = Paths.get("/foo/bar");
try {
List<Path> directories =
Files.walk(directory)
.filter(Files::isDirectory)
.collect(Collectors.toList());
} catch (IOException e) {
// process exception
}
A jeśli z powodów przestarzałych potrzebujesz uzyskać Listę File, możesz po prostu dodać map(Path::toFile)operację przed kolekcją:
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)prawdopodobnie to samo co Files.walk(Path,1).
Files.list(Path)jest uczciwą alternatywą, jeśli nie chcemy iterować rekurencyjnie folderów. Aby iterować foldery rekurencyjnie, walk()lepiej pasuje.
Na liście odpowiedzi brakuje rozwiązania, które u mnie zadziałało. Dlatego zamieszczam tutaj to rozwiązanie:
File[]dirs = new File("/mypath/mydir/").listFiles((FileFilter)FileFilterUtils.directoryFileFilter());
Tutaj użyłem org.apache.commons.io.filefilter.FileFilterUtilsz Apache commons-io-2.2.jar. Jego dokumentacja jest dostępna tutaj: https://commons.apache.org/proper/commons-io/javadocs/api-2.2/org/apache/commons/io/filefilter/FileFilterUtils.html
Biorąc pod uwagę katalog początkowy jako plik String
Stringścieżkę jako parametr. W metodzie:listFilesmetodyOto rozwiązanie dla mojego kodu. Zrobiłem tylko małą zmianę od pierwszej odpowiedzi . Spowoduje to wyświetlenie wszystkich folderów tylko w wybranym katalogu wiersz po wierszu:
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!");
}