337

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 framework or nio

Adil
  • 4,503
  • 10
  • 46
  • 63
Quintin Par
  • 15,862
  • 27
  • 93
  • 146
  • 3
    I have just completed [Test Results](https://github.com/brettryan/io-recurse-tests) that provide performance tests for many of the answers. Unsurprisingly all NIO based answers perform best. The commons-io answer is clearly the worst performer with over twice the run length. – Brett Ryan Jun 29 '15 at 05:02
  • 2
    Java8 : Files.walk ? – Benj Oct 04 '16 at 15:51

30 Answers30

462

Java 8 provides a nice stream to process all files in a tree.

try (Stream<Path> stream = Files.walk(Paths.get(path))) {
    stream.filter(Files::isRegularFile)
          .forEach(System.out::println);
}

This provides a natural way to traverse files. Since it's a stream you can do all nice stream operations on the result such as limit, grouping, mapping, exit early etc.

UPDATE: I might point out there is also Files.find which takes a BiPredicate that could be more efficient if you need to check file attributes.

Files.find(Paths.get(path),
           Integer.MAX_VALUE,
           (filePath, fileAttr) -> fileAttr.isRegularFile())
        .forEach(System.out::println);

Note that while the JavaDoc eludes that this method could be more efficient than Files.walk it is effectively identical, the difference in performance can be observed if you are also retrieving file attributes within your filter. In the end, if you need to filter on attributes use Files.find, otherwise use Files.walk, mostly because there are overloads and it's more convenient.

TESTS: As requested I've provided a performance comparison of many of the answers. Check out the Github project which contains results and a test case.

Sergey
  • 3,253
  • 2
  • 33
  • 55
Brett Ryan
  • 26,937
  • 30
  • 128
  • 163
  • 2
    How does the performance of this compare with pre-java 8 methods? My current directory traversal is too slow and I'm looking for something that will speed it up. – Sridhar Sarnobat Jun 25 '15 at 22:18
  • 1
    I'm writing up some tests containing most of the variants in the answers provided. So far, it seems that using `Files.walk` with a parallel stream is the best, followed closely by `Files.walkFileTree` which is only marginally slower. The accepted answer using commons-io is by far the slowest by my tests to be 4 times slower. – Brett Ryan Jun 28 '15 at 13:54
  • Tests are complete and a [project added to Github, check it out for the results](https://github.com/brettryan/io-recurse-tests). The short answer is use any NIO flavour of the answers provided. – Brett Ryan Jun 29 '15 at 05:13
  • 3
    @BrettRyan, I tried your solution but I get an exception `Exception in thread "main" java.io.UncheckedIOException: java.nio.file.AccessDeniedException`. How could I correct it – Kachna Sep 05 '15 at 08:58
  • 7
    How do I get an actual list of files from this? – dessalines Oct 09 '15 at 15:58
  • 1
    @thouliha instead of `forEach` use `collect` with a set or list collector such as `.collect(Collectors.toList())`. If you can avoid a collector in your logic the better as you will be using less objects and processing can be faster. – Brett Ryan Oct 10 '15 at 00:58
  • @BrettRyan am I correct that by default Files.walk() doesn't follow symbolic links? If so and one wanted to follow symlinks, it looks like the first chunk of code could instead be `Files.walk(Paths.get(path), FileVisitOption.FOLLOW_LINKS)` – Matt Passell Mar 03 '16 at 14:36
  • Apologies for the delayed response @MattPassell, you are correct. There is a caveat to using this when a circular link is found, you won't end up with a recursive loop though you unfortunately will get a [FileSystemLoopException](https://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystemLoopException.html) being thrown which is wrapped in an [UncheckedIOException](https://docs.oracle.com/javase/8/docs/api/java/io/UncheckedIOException.html) – Brett Ryan Mar 10 '16 at 22:31
  • 1
    @BrettRyan thanks, good point. In the particular spot I'm using it, the starting path might be a symlink, but from that point down, it isn't. That allowed me to do something like this `Path basePath = Files.isSymbolicLink(basePath) ? Files.readSymbolicLink(basePath) : basePath;` and then walk the tree without following links. :) – Matt Passell Mar 11 '16 at 15:32
  • 1
    @BrettRyan "instead of forEach use collect" Sorry but I'm still unclear. Calling `.collect(stagingFileList::add)` on the resulting stream from that code gets me `Collector is not a functional interface` on the collect parameter. This stream stuff is cool but I'm not completely sure what I'm looking at anymore to fix this. – Alkanshel Jan 13 '17 at 03:08
  • This is what I'm attempting-- `Files.find( Paths.get(path), Integer.MAX_VALUE, (filePath, fileAttr) -> fileAttr.isRegularFile()) .collect(list::add);` – Alkanshel Jan 13 '17 at 03:11
  • 1
    @Amalgovinus what you're looking for is a collector, what you've given is a method reference. Replace list::add with `Collectors.toList()` – Brett Ryan Jan 13 '17 at 03:43
  • Watch out for this issue: https://bugs.openjdk.java.net/browse/JDK-8039910 More info here: https://stackoverflow.com/questions/22867286/files-walk-calculate-total-size – Jonathan Hult Jan 16 '17 at 05:45
  • 3
    Files.walk looks nice, but quite often is useless.... it throws exception if you don't have an access to even one file... and you got nothing... – razor Nov 22 '18 at 11:17
  • @BrettRyan - What does it mean for a dir to be "open", thus requiring it to be closed? The [javadoc](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/nio/file/Files.html) says to put walk() and find() into a try-with-resources block. I've never heard of the concept of an "open dir" – Vahid Pazirandeh Apr 01 '20 at 20:22
  • You must put Files.walk in a try-with-resources block since it's backed by DirectoryStreams (https://docs.oracle.com/javase/8/docs/api/java/nio/file/DirectoryStream.html ) which says: "Failure to close the stream may result in a resource leak. The try-with-resources statement provides a useful construct to ensure that the stream is closed" – joseph Oct 08 '21 at 00:48
  • Please see https://stackoverflow.com/a/69489309/1810962 for a more complete answer. – joseph Oct 08 '21 at 01:06
168

FileUtils have iterateFiles and listFiles methods. Give them a try. (from commons-io)

Edit: You can check here for a benchmark of different approaches. It seems that the commons-io approach is slow, so pick some of the faster ones from here (if it matters)

Thunderforge
  • 19,637
  • 18
  • 83
  • 130
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 46
    FYI/TLDR: if you just want to list all files recursively with no filtering, do `FileUtils.listFiles(dir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE)`, where `dir` is a File object that points to the base directory. – andronikus Apr 27 '12 at 17:53
  • 2
    You might want to consider using `listFilesAndDirs()`, as `listFiles()` does not return empty folders. – schnatterer Feb 14 '14 at 11:41
  • 1
    @MikeFHay Looking at the FileUtils code, I think that vould be `FileUtils.listFiles(dir, true, true)`. using `FileUtils.listFiles(dir, null, true)` will throw an Exception, while `FileUtils.listFiles(dir, true, null)` will list all files without looking into subdirectories. – ocramot May 23 '14 at 09:15
  • How about a JDK native library? I can implement this easy but I would simply be C&P from other places – Christian Bongiorno Sep 17 '14 at 21:13
  • 1
    I'm putting some tests together, but so far this seems to be performing 4 times slower than that of using JDK8 or JDK7 alternatives. Symlinks also prove to be problematic with this approach, especially where they link to directories higher in the tree, this causes the method to never return, this can be avoided by handling the filter, but unfortunately the symlinks themselves don't get visited even as a file. – Brett Ryan Jun 28 '15 at 13:58
145

// Ready to run

import java.io.File;

public class Filewalker {

    public void walk( String path ) {

        File root = new File( path );
        File[] list = root.listFiles();

        if (list == null) return;

        for ( File f : list ) {
            if ( f.isDirectory() ) {
                walk( f.getAbsolutePath() );
                System.out.println( "Dir:" + f.getAbsoluteFile() );
            }
            else {
                System.out.println( "File:" + f.getAbsoluteFile() );
            }
        }
    }

    public static void main(String[] args) {
        Filewalker fw = new Filewalker();
        fw.walk("c:\\" );
    }

}
carlspring
  • 31,231
  • 29
  • 115
  • 197
stacker
  • 68,052
  • 28
  • 140
  • 210
  • 10
    Just beware that for symbolic links that point to a path higher in the path hierarchy will cause the method to never end. Consider a path with a symlink that points to `-> .`. – Brett Ryan Jun 28 '15 at 13:16
  • 2
    This is just essentially a bad implementation of Files.walkFileTree. I would reccomend that people look at FIles.walkFileTree instead of trying to roll it yourself... It has handling for the exact problem @BrettRyan pointed it. – Tyler Nichols Jun 18 '18 at 21:44
  • Path may vary depending on where the Filewalker file is. Use `"/"`,`"./"` or `"../"` for root directory, current working directory, and parent directory, respectively – Moses Kirathe Jun 13 '20 at 21:39
72

Java 7 will have has Files.walkFileTree:

If you provide a starting point and a file visitor, it will invoke various methods on the file visitor as it walks through the file in the file tree. We expect people to use this if they are developing a recursive copy, a recursive move, a recursive delete, or a recursive operation that sets permissions or performs another operation on each of the files.

There is now an entire Oracle tutorial on this question.

kritzikratzi
  • 19,662
  • 1
  • 29
  • 40
yawn
  • 8,014
  • 7
  • 29
  • 34
29

No external libraries needed.
Returns a Collection so you can do whatever you want with it after the call.

public static Collection<File> listFileTree(File dir) {
    Set<File> fileTree = new HashSet<File>();
    if(dir==null||dir.listFiles()==null){
        return fileTree;
    }
    for (File entry : dir.listFiles()) {
        if (entry.isFile()) fileTree.add(entry);
        else fileTree.addAll(listFileTree(entry));
    }
    return fileTree;
}
aprodan
  • 559
  • 5
  • 17
Petrucio
  • 5,491
  • 1
  • 34
  • 33
19

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.

Stefan Schmidt
  • 1,152
  • 11
  • 18
  • 6
    From the documentation of `listFiles()`: “If this abstract pathname does not denote a directory, then this method returns `null`.” – hfs Nov 17 '11 at 09:30
  • Improved variant public static Collection listFileTree(File dir) { if (null == dir || !dir.isDirectory()) { return Collections.emptyList(); } final Set fileTree = new HashSet(); for (File entry : dir.listFiles()) { if (entry.isFile()) { fileTree.add(entry); } else { fileTree.addAll(listFileTree(entry)); } } return fileTree; } – Ben Nov 22 '13 at 23:30
  • To me this is the most concise answer that is recursive. – William May 31 '18 at 14:30
16

I prefer using a queue over recursion for this kind of simple traversion:

List<File> allFiles = new ArrayList<File>();
Queue<File> dirs = new LinkedList<File>();
dirs.add(new File("/start/dir/"));
while (!dirs.isEmpty()) {
  for (File f : dirs.poll().listFiles()) {
    if (f.isDirectory()) {
      dirs.add(f);
    } else if (f.isFile()) {
      allFiles.add(f);
    }
  }
}
benroth
  • 2,468
  • 3
  • 24
  • 25
  • But your algorithm cannot print with indented output. Dirs and files are messed. Any solution? – Wei Feb 01 '13 at 05:54
13

just write it yourself using simple recursion:

public List<File> addFiles(List<File> files, File dir)
{
    if (files == null)
        files = new LinkedList<File>();

    if (!dir.isDirectory())
    {
        files.add(dir);
        return files;
    }

    for (File file : dir.listFiles())
        addFiles(files, file);
    return files;
}
pstanton
  • 35,033
  • 24
  • 126
  • 168
  • 1
    Please! let the caller initialize the files list so it hasn't have to check its nullity each time. If you want create a second (public) method that creates the list, calls this internal method and returns the complete list. – helios Jan 13 '10 at 11:44
  • 1
    whatever. a null check isn't very expensive, convenience + personal preference aside i think he'll get the point. – pstanton Jan 13 '10 at 11:45
8

With Java 7 you can use the following class:

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class MyFileIterator extends SimpleFileVisitor<Path>
{
    public MyFileIterator(String path) throws Exception
    {
        Files.walkFileTree(Paths.get(path), this);
    }

    @Override
    public FileVisitResult visitFile(Path file,
            BasicFileAttributes attributes) throws IOException
    {
        System.out.println("File: " + file);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult preVisitDirectory(Path dir,
            BasicFileAttributes attributes) throws IOException
    {
        System.out.println("Dir: " + dir);
        return FileVisitResult.CONTINUE;
    }
}
chao
  • 1,893
  • 2
  • 23
  • 27
8

This code is ready to run

public static void main(String... args) {
    File[] files = new File("D:/").listFiles();
    if (files != null) 
       getFiles(files);
}

public static void getFiles(File[] files) {
    for (File file : files) {
        if (file.isDirectory()) {
            getFiles(file.listFiles());
        } else {
            System.out.println("File: " + file);
        }
    }
}
Ebraheem Alrabeea
  • 2,130
  • 3
  • 23
  • 42
7

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).

Michał Niklas
  • 53,067
  • 18
  • 70
  • 114
7

In Java 8, we can now use the Files utility to walk a file tree. Very simple.

Files.walk(root.toPath())
      .filter(path -> !Files.isDirectory(path))
      .forEach(path -> System.out.println(path));
Roy Kachouh
  • 1,855
  • 16
  • 24
4

Apart from the recursive traversal one can use a Visitor based approach as well.

Below code is uses Visitor based approach for the traversal.It is expected that the input to the program is the root directory to traverse.

public interface Visitor {
    void visit(DirElement d);
    void visit(FileElement f);
}

public abstract class Element {
    protected File rootPath;
    abstract void accept(Visitor v);

    @Override
    public String toString() {
        return rootPath.getAbsolutePath();
    }
}

public class FileElement extends Element {
    FileElement(final String path) {
        rootPath = new File(path);
    }

    @Override
    void accept(final Visitor v) {
        v.visit(this);
    }
}

public class DirElement extends Element implements Iterable<Element> {
    private final List<Element> elemList;
    DirElement(final String path) {
        elemList = new ArrayList<Element>();
        rootPath = new File(path);
        for (File f : rootPath.listFiles()) {
            if (f.isDirectory()) {
                elemList.add(new DirElement(f.getAbsolutePath()));
            } else if (f.isFile()) {
                elemList.add(new FileElement(f.getAbsolutePath()));
            }
        }
    }

    @Override
    void accept(final Visitor v) {
        v.visit(this);
    }

    public Iterator<Element> iterator() {
        return elemList.iterator();
    }
}

public class ElementWalker {
    private final String rootDir;
    ElementWalker(final String dir) {
        rootDir = dir;
    }

    private void traverse() {
        Element d = new DirElement(rootDir);
        d.accept(new Walker());
    }

    public static void main(final String[] args) {
        ElementWalker t = new ElementWalker("C:\\temp");
        t.traverse();
    }

    private class Walker implements Visitor {
        public void visit(final DirElement d) {
            System.out.println(d);
            for(Element e:d) {
                e.accept(this);
            }
        }

        public void visit(final FileElement f) {
            System.out.println(f);
        }
    }
}
Mohammad Faisal
  • 5,783
  • 15
  • 70
  • 117
sateesh
  • 27,947
  • 7
  • 36
  • 45
3

You can use below code to get a list of files of specific folder or directory recursively.

public static void main(String args[]) {

        recusiveList("D:");

    }

    public static void recursiveList(String path) {

        File f = new File(path);
        File[] fl = f.listFiles();
        for (int i = 0; i < fl.length; i++) {
            if (fl[i].isDirectory() && !fl[i].isHidden()) {
                System.out.println(fl[i].getAbsolutePath());
                recusiveList(fl[i].getAbsolutePath());
            } else {
                System.out.println(fl[i].getName());
            }
        }
    }
Rakesh Chaudhari
  • 3,310
  • 1
  • 27
  • 25
2

I came up with this for printing all the files/file names recursively.

private static void printAllFiles(String filePath,File folder) {
    if(filePath==null) {
        return;
    }
    File[] files = folder.listFiles();
    for(File element : files) {
        if(element.isDirectory()) {
            printAllFiles(filePath,element);
        } else {
            System.out.println(" FileName "+ element.getName());
        }
    }
}
kanaparthikiran
  • 523
  • 12
  • 15
2

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);
    }
Omkar T
  • 755
  • 8
  • 19
2
List<Path> filePaths = Files
    .find(Paths.get(dir), Integer.MAX_VALUE, (filePath, fileAttr) -> fileAttr.isRegularFile() || fileAttr.isDirectory())
    .collect(Collectors.toList());

filePaths will have files and folder list which can be iterated and proceed further.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
1

Non-recursive BFS with a single list (particular example is searching for *.eml files):

    final FileFilter filter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            return file.isDirectory() || file.getName().endsWith(".eml");
        }
    };

    // BFS recursive search
    List<File> queue = new LinkedList<File>();
    queue.addAll(Arrays.asList(dir.listFiles(filter)));

    for (ListIterator<File> itr = queue.listIterator(); itr.hasNext();) {
        File file = itr.next();
        if (file.isDirectory()) {
            itr.remove();
            for (File f: file.listFiles(filter)) itr.add(f);
        }
    }
bobah
  • 18,364
  • 2
  • 37
  • 70
1

My version (of course I could have used the built in walk in Java 8 ;-) ):

public static List<File> findFilesIn(File rootDir, Predicate<File> predicate) {
        ArrayList<File> collected = new ArrayList<>();
        walk(rootDir, predicate, collected);
        return collected;
    }

    private static void walk(File dir, Predicate<File> filterFunction, List<File> collected) {
        Stream.of(listOnlyWhenDirectory(dir))
                .forEach(file -> walk(file, filterFunction, addAndReturn(collected, file, filterFunction)));
    }

    private static File[] listOnlyWhenDirectory(File dir) {
        return dir.isDirectory() ? dir.listFiles() : new File[]{};
    }

    private static List<File> addAndReturn(List<File> files, File toAdd, Predicate<File> filterFunction) {
        if (filterFunction.test(toAdd)) {
            files.add(toAdd);
        }
        return files;
    }
user1189332
  • 1,773
  • 4
  • 26
  • 46
1

Here a simple but perfectly working solution using recursion:

public static List<Path> listFiles(String rootDirectory)
{
    List<Path> files = new ArrayList<>();
    listFiles(rootDirectory, files);

    return files;
}

private static void listFiles(String path, List<Path> collectedFiles)
{
    File root = new File(path);
    File[] files = root.listFiles();

    if (files == null)
    {
        return;
    }

    for (File file : files)
    {
        if (file.isDirectory())
        {
            listFiles(file.getAbsolutePath(), collectedFiles);
        } else
        {
            collectedFiles.add(file.toPath());
        }
    }
}
BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
1
    private void fillFilesRecursively(File file, List<File> resultFiles) {
        if (file.isFile()) {
            resultFiles.add(file);
        } else {
            for (File child : file.listFiles()) {
                fillFilesRecursively(child, resultFiles);
            }
        }
    }
legendmohe
  • 750
  • 7
  • 11
1

Kotlin has FileTreeWalk for this purpose. For example:

dataDir.walkTopDown().filter { !it.isDirectory }.joinToString("\n") {
   "${it.toRelativeString(dataDir)}: ${it.length()}"
}

Will produce a text list of all the non-directory files under a given root, one file per line with the path relative to the root and length.

Clyde
  • 7,389
  • 5
  • 31
  • 57
1

The accepted answer is great, however it breaks down when you want to do IO inside the lambda.

Here is what you can do if your action declares IOExceptions.

You can treat the filtered stream as an Iterable, and then do your action in a regular for-each loop. This way, you don't have to handle exceptions inside a lambda.

try (Stream<Path> pathStream = Files.walk(Paths.get(path))
        .filter(Files::isRegularFile)) {

    for (Path file : (Iterable<Path>) pathStream::iterator) {
        // something that throws IOException
        Files.copy(file, System.out);
    }
}

Found that trick here: https://stackoverflow.com/a/32668807/1207791

cfstras
  • 1,613
  • 15
  • 21
1

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);
}
Michael
  • 416
  • 1
  • 6
  • 16
1
public static String getExten(String path) {
    int i = path.lastIndexOf('.');
    if (i > 0) {
       return path.substring(i);
    }
    else return "";
}
public static List<String> GetAllFiles(String path, List<String>fileList){
    File file = new File(path);
    
    File[] files = file.listFiles();
    for(File folder:files) {
        if(extensions.contains(getExten(folder.getPath()))) {
            fileList.add(folder.getPath());
        }
    }
    File[] direcs = file.listFiles(File::isDirectory);
    for(File dir:direcs) {
        GetAllFiles(dir.getPath(),fileList);
    }
    return fileList;
    
}

This is a simple recursive function that should give you all the files. extensions is a list of string that contains only those extensions which are accepted. Example extensions = [".txt",".docx"] etc.

1

The accepted answer is poor because it can result in a resource leak.

Files.walk is backed by DirectoryStreams.

The returned stream encapsulates one or more DirectoryStreams. If timely disposal of file system resources is required, the try-with-resources construct should be used to ensure that the stream's close method is invoked after the stream operations are completed. Operating on a closed stream will result in an IllegalStateException.

A DirectoryStream must be closed as specified in it's javadoc:

A DirectoryStream is opened upon creation and is closed by invoking the close method. Closing a directory stream releases any resources associated with the stream. Failure to close the stream may result in a resource leak. The try-with-resources statement provides a useful construct to ensure that the stream is closed:

Path dir = ...
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
    for (Path entry: stream) {
        ...
    }
}

As a result, the true answer is:

try (Stream<Path> stream = Files.walk(Paths.get(path))) {
    // Do something with the stream.
    stream.filter(Files::isRegularFile)
          .forEach(System.out::println);
}
joseph
  • 2,429
  • 1
  • 22
  • 43
0

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.

Ralf R.
  • 61
  • 4
0

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);
}
Yessy
  • 1,172
  • 1
  • 8
  • 13
-1

Based on stacker answer. Here is a solution working in JSP without any external libraries so you can put it almost anywhere on your server:

<!DOCTYPE html>
<%@ page session="false" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>
<%@ page contentType="text/html; charset=UTF-8" %>

<%!
    public List<String> files = new ArrayList<String>();
    /**
        Fills files array with all sub-files.
    */
    public void walk( File root ) {
        File[] list = root.listFiles();

        if (list == null) return;

        for ( File f : list ) {
            if ( f.isDirectory() ) {
                walk( f );
            }
            else {
                files.add(f.getAbsolutePath());
            }
        }
    }
%>
<%
    files.clear();
    File jsp = new File(request.getRealPath(request.getServletPath()));
    File dir = jsp.getParentFile();
    walk(dir);
    String prefixPath = dir.getAbsolutePath() + "/";
%>

Then you just do something like:

    <ul>
        <% for (String file : files) { %>
            <% if (file.matches(".+\\.(apk|ipa|mobileprovision)")) { %>
                <li><%=file.replace(prefixPath, "")%></li>
            <% } %>
        <% } %>
    </ul>
Nux
  • 9,276
  • 5
  • 59
  • 72
  • 1
    While it probably works, the question is about file browsing, not rendering of browsed files. Better expose your algorithm as such, it is not a recommended practice to embed business logic inside a JSP. – Samuel Kerrien Jun 15 '15 at 09:54
  • That depends what you are doing. In an enterprise-size application you are absolutely right. If you just need this as a drop-in to a simple, standalone listing, then this is perfectly fine. – Nux Jun 24 '15 at 12:22
-1
import java.io.File;

public class Main {
    public static void main(String[] args) {
        loopFiles(new File("C:\\Users\\serge.klimkovitch\\Documents"));
    }

    private static void loopFiles(File element) {
        if (element.isDirectory()) {
            for (File currentFile : element.listFiles()) {
                loopFiles(currentFile);
                System.out.println(currentFile);
            }
        }
    }
}
sklimkovitch
  • 251
  • 4
  • 8