How do I recursively list all files under a directory in Java? Does the framework provide any utility?
I saw a lot of hacky implementations. But none from the fra
Another way you can do even if someone already provide Java 8 walk.
This one will provide you all files recursively
private Stream<File> files(File file) {
return file.isDirectory()
? Arrays.stream(file.listFiles()).flatMap(this::files)
: Stream.of(file);
}
I think this should do the work:
File dir = new File(dirname);
String[] files = dir.list();
This way you have files and dirs. Now use recursion and do the same for dirs (File
class has isDirectory()
method).
Lists all files with provided extensions,with option to scan subfolders (recursive)
public static ArrayList<File> listFileTree(File dir,boolean recursive) {
if (null == dir || !dir.isDirectory()) {
return new ArrayList<>();
}
final Set<File> fileTree = new HashSet<File>();
FileFilter fileFilter = new FileFilter() {
private final String[] acceptedExtensions = new String[]{"jpg", "png", "webp", "jpeg"};
@Override
public boolean accept(File file) {
if (file.isDirectory()) {
return true;
}
for (String extension : acceptedExtensions) {
if (file.getName().toLowerCase().endsWith(extension)) {
return true;
}
}
return false;
}
};
File[] listed = dir.listFiles(fileFilter);
if(listed!=null){
for (File entry : listed) {
if (entry.isFile()) {
fileTree.add(entry);
} else if(recursive){
fileTree.addAll(listFileTree(entry,true));
}
}
}
return new ArrayList<>(fileTree);
}
base on @Michael answer, add check whether listFiles return null
static Stream<File> files(File file) {
return file.isDirectory()
? Optional.ofNullable(file.listFiles()).map(Stream::of).orElseGet(Stream::empty).flatMap(MainActivity::files)
: Stream.of(file);
}
or use Lightweight-Stream-API, which support Android5 & Android6
static Stream<File> files(File f) {
return f.isDirectory() ? Stream.ofNullable(f.listFiles()).flatMap(MainActivity::files) : Stream.of(f);
}
I would go with something like:
public void list(File file) {
System.out.println(file.getName());
File[] children = file.listFiles();
for (File child : children) {
list(child);
}
}
The System.out.println is just there to indicate to do something with the file. there is no need to differentiate between files and directories, since a normal file will simply have zero children.
Example outputs *.csv files in directory recursive searching Subdirectories using Files.find() from java.nio:
String path = "C:/Daten/ibiss/ferret/";
logger.debug("Path:" + path);
try (Stream<Path> fileList = Files.find(Paths.get(path), Integer.MAX_VALUE,
(filePath, fileAttr) -> fileAttr.isRegularFile() && filePath.toString().endsWith("csv"))) {
List<String> someThingNew = fileList.sorted().map(String::valueOf).collect(Collectors.toList());
for (String t : someThingNew) {
t.toString();
logger.debug("Filename:" + t);
}
}
Posting this example, as I had trouble understanding howto pass the filename parameter in the #1 example given by Bryan, using foreach on Stream-result -
Hope this helps.