Recursive directory traversal in java or android ?

 
One way of traversing , a directory content recursively , is to use , the new java .nio api , which provides some functions , related to that . This api , also works on android version 8 , and higher .

import static java .lang .System .out;

import java .io .IOException;

import java .nio .file .DirectoryStream;

import java .nio .file .Path;
import java .nio .file .Paths;
import java .nio .file .Files;

public class List_Recursive{
    public static final int final_abnormal_exit = 1 ;
    public static void main (String args [ ] ){

        if (args .length  < 1 )
            System .exit (final_abnormal_exit );
        /* args[0 ] contains the directory name ,
          to print its content recursively .
          This is a String .*/

        Path path = Paths .get (args [0 ] );
        /* Convert the String to a Path .*/

        ls_R (path );
        /*Call ls_R to print the directory contents
          recursively .*/ }

    public static void ls_R (Path path ){
        try (DirectoryStream <Path > paths  =
                Files .newDirectoryStream (path ) ){
                /*Create a directory stream , to iterate
                  over the directory contents .*/

            for (Path t_path : paths ){
                out .println (t_path .toString ( ) );
                //Print the path

                if (Files .isDirectory (t_path ) )
                /*If path is directory , call ls_R
                  to print its content .*/

                    ls_R (t_path ); }}

        catch (IOException | SecurityException exception ){
            /*Files .newDirectoryStream  will throw the
              exceptions , NotDirectoryException , IOException ,
              SecurityException .
              It is sufficient to catch IOException , and
              SecurityException , since NotDirectoryException is
              caught using IOException .*/

            out .println (exception ); }}}
/*
$ javac List_Recursive.java
$ java List_Recursive 'tmp'
    tmp/a
    tmp/a/b
    tmp/a/b/c
    tmp/a/b/c/d
    tmp/b
    tmp/c
    tmp/d
    tmp/e
    tmp/Demo2.class
    tmp/Demo2.java
    tmp/i
    tmp/o
    tmp/pp
    tmp/r
    tmp/r/a
    tmp/r/b
    tmp/s
    tmp/z */          

This example shows how to print a directory content , recursively using a filter , so for example , to print only the directories , and not the files , or only the files , and not the directories …

import static java .lang .System .out;
import java .io .IOException;

import java .nio .file .Paths;
import java .nio .file .Path;
import java .nio .file .Files;

import java .nio .file .DirectoryStream;

public class Print_Directories_Filter {
    public static final int final_abnormal_exit = 1;

    public static void main (String args [ ] ){
        if (args .length < 1 )
            System .exit (final_abnormal_exit );
        Path path = Paths .get (args [0 ] );
        Path_Filter filter = new Path_Filter ( );
        ls_F (path , filter ); }

    public static void ls_F (Path path , DirectoryStream .Filter <Path > filter ){
        try (DirectoryStream <Path > paths =
                Files .newDirectoryStream (path , filter ) ){
            for (Path t_path : paths )
                    out .println (t_path ); }
        catch (IOException | SecurityException exception ){/* Do Something .*/ } }}


class Path_Filter implements DirectoryStream .Filter <Path >{
    public boolean accept (Path path ) throws IOException{
        return Files .isRegularFile (path ); }}
/*
$ javac Print_Directories_Filter.java
$ java Print_Directories_Filter "tmp"
tmp/b
tmp/c
tmp/d
tmp/e
tmp/Demo2.class
tmp/Demo2.java
tmp/i
tmp/o
*/

Walking the file tree , can also be performed using Files .walkFileTree . The advantages of this method , is that traversal is done lazily , and that it prevents cycles , such as when a symbolic link , points to a parent directory .

import static java .lang .System .out;
import static java .lang .System .err;

import java .io .IOException;

import java .util .Set;
import java .util .HashSet;
import java .util .EnumSet;

import java .nio .file .FileVisitResult;
import java .nio .file .FileVisitOption;

import java .nio .file .attribute .BasicFileAttributes;

import java .nio .file .Paths;
import java .nio .file .Path;

import java .nio .file .Files;

import java .nio .file .FileVisitor;

public class WalkFile_Tree{
    public static final int final_abnormal_exit = 1;
    public static void main (String args [ ] ){
        if (args .length != 1 )
            System .exit (final_abnormal_exit );

        Path path = Paths .get (args [0 ] );
        int maxDepth = Integer .MAX_VALUE ;

        Do_FileAction do_FileAction = new Do_FileAction ();

        Set<FileVisitOption> options = new HashSet<>() ;
        /* Options when walking the file Tree
           by default not follow symbolick links .*/

        options.add (FileVisitOption .FOLLOW_LINKS );
        /* Follow symbolic links when walking the file
           tree .*/

        try{
            Files .walkFileTree (path , options , maxDepth , do_FileAction );
            /* Follow Symbolic Links .*/

            Files .walkFileTree (path ,
                    EnumSet .noneOf (FileVisitOption .class) , maxDepth , do_FileAction );
            /* Do not Follow Symbolic Links .*/ }
        catch (IllegalArgumentException
                | IOException | SecurityException  exception ){ /* Handle exception .*/ } }}

class Do_FileAction implements FileVisitor<Path>{
    /* Implement FileVisitor , to perform an action .*/

    @Override
    public FileVisitResult preVisitDirectory (Path path , BasicFileAttributes attrs ) throws IOException{
        path_details_Print (path , attrs );
        return FileVisitResult .CONTINUE; }

    @Override
    public FileVisitResult visitFile (Path path , BasicFileAttributes attrs ) throws IOException{
        path_details_Print (path , attrs );
        return FileVisitResult .CONTINUE; }

    @Override
    public FileVisitResult postVisitDirectory (Path path , IOException exc ) throws IOException{
        return FileVisitResult .CONTINUE; }

    @Override
    public FileVisitResult visitFileFailed (Path path , IOException exc ) throws IOException{
        err .println (path );
        err .println (exc ) ;
        return FileVisitResult .CONTINUE; }

    private void path_details_Print (Path path ,
            BasicFileAttributes basic_attributes ){
        out .println ("Path is ? " + path );
        out .println ("\tIs Directory ? " + basic_attributes .isDirectory ( ) );
        out .println ("\tIs Regular File ? " + basic_attributes .isRegularFile ( ) );
        out .println ("\tIs Symbolic Link ? " + basic_attributes .isSymbolicLink ( ) );
        out .println ("\tIs not regular file, directory, symbolic link ? " +
                        basic_attributes .isOther ( ) );
        out .println ("\tCreation Time ? " + basic_attributes .creationTime ( ) );
        out .println ("\tLast Access Time ? " + basic_attributes .lastAccessTime ( ) );
        out .println ("\tLast Modified Time? " + basic_attributes .lastModifiedTime ( ) );
        out .println ("\tSize in Bytes ? " + basic_attributes .size ( ) ); }}
/*
$ javac WalkFile_Tree.java
$ java WalkFile_Tree "tmp"
Path is ? tmp
        Is Directory ? true
        Is Regular File ? false
        Is Symbolic Link ? false
        Is not regular file, directory, symbolic link ? false
        Creation Time ? 2021-02-09T22:50:11Z
        Last Access Time ? 2021-02-13T17:12:21Z
        Last Modified Time? 2021-02-13T16:44:34Z
        Size in Bytes ? 544
Path is ? tmp/a
        Is Directory ? true
        Is Regular File ? false
        Is Symbolic Link ? false
        Is not regular file, directory, symbolic link ? false
        Creation Time ? 2021-02-11T23:48:01Z
        Last Access Time ? 2021-02-13T17:12:21Z
        Last Modified Time? 2021-02-11T23:48:01Z
        Size in Bytes ? 102 */