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 */