List all directories using java

Java NIO.2 Recursive Directory Listing Example

In this tutorial, we will teach you how to list all the directories inside a folder recursively in Java, using NIO.2. Specifically, we will look into FileVisitor interface ( java.nio.file.FileVisitor ) and implement the methods available in this interface, to traverse a folder. We will focus on listing the following items during our traversal in this example:

  • List Sub directory Name
  • List Absolute path of the directory
  • List Parent directory name
  • List relative path specific to a fixed path
  • Convert the sub-directory name to URI.

There are much more, we will look at them in our advanced examples later. The sample directory structure for this example is provided below:

FileVisitor Interface – Access Files and Directories

java.nio.file.SimpleFileVisitor interface implements FileVisitor, and offers the key methods postVisitDirectory , preVisitDirectory , visitFile and visitFileFailed . In order to recursively list all directories, you can extend SimpleFileVisitor class, and override only those methods that you want, depending on your requirements. A brief overview on the methods we require for this tutorial / that we need to override is presented below:

postVisitDirectory: This method is invoked after all the sub-directories / directory is visited. (for now, this much of explanation would be sufficient for this ). We will make use of this method, to traverse through all the sub-directories.

visitFileFailed: In the context of this post, this method will be invoked if the directory cannot be opened / traversed due to some reason. In this case, we get an exception back, which can be printed on the screen. You can take a decision to either abort the program execution, or continue accessing other directories.

Both these methods return an object of type, java.nio.file.FileVisitResult , through which you can either CONTINUE or TERMINATE the execution. Our approach would be to implement postVisitDirectory method to get list of directories, and visitFileFailed method to handle exceptions in this process.

walkFileTree – traverse directory structure:

ok, we got basic methods to traverse directories, but how do we initiate the traversal? java.nio.file.Files class has a method walkFileTree ,(there are two versions of this method, we will use the simple one for this tutorial) which accepts a Path from where you have to start searching, and accepts a FileVisitor class, which it has to obey in the traversal process. This is the key linker for our program. It connects a path in our system to the methods we wrote earlier, so that all the directories are visited. The traversal is always done by depth first search method. This method continues, until all files are traversed or a TERMINATE is encountered.

The Java Program that prints all sub directories inside a folder recursively using NIO.2 should start by defining the generic FileVisitor interface method behaviour. It should then accept a Path where it can execute the generic methods defined, and pass this path to walkFileTree method, which will then call these methods for every directory encountered. Diagrammatically, it is shown below:

Читайте также:  Http www toyota senkai ru ruk prado html
Approach in NIO.2 to list directory contents - Java Pseudo logic
Approach in NIO.2 to list directory contents — Java Pseudo logic

postVisitDirectory Implementation – Print Directory properties

In this method, we list all the output we want for every directory, using the methods available in Path class. The methods we use for our listing is shown below:

  • getFileName – to print the directory name.
  • toAbsolutePath – convert directory name to absolute path
  • getParent – to print the parent directory name
  • relativize – to print the path relative to a specified path
  • toUri – to convert the directory path to URI
 @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc)  System.out.println(""); // Print Name of the directory System.out.println("Directory Name: " + dir.getFileName()); // Print absolute path for the directory System.out.println("Absolute Path: " + dir.toAbsolutePath()); // Print parent directory name System.out.println("Parent Directory: " + dir.getParent().getFileName()); // continue to the next directory // Get Relative path to C: Path relative_path_to = Paths.get("C:/"); System.out.println("Relative Path: " + dir.relativize(relative_path_to)); // URI of the directory System.out.println("URI: " + dir.toUri()); return FileVisitResult.CONTINUE; > 

Note that, we override this method as our class will extend SimpleFileVisitor class.

visitFileFailed Implementation – Handle Exception while Traversing:

We just print the exception and do nothing here. This is a tutorial for beginners, so we just give a CONTINUE when we encounter this exception.

 @Override public FileVisitResult visitFileFailed(Path file, IOException traversalException)  // we throw an exception if the directory cannot be accessed for any reason System.out.println(traversalException); // and continue traversing other directories return FileVisitResult.CONTINUE; > 

Complete Java Program – List all directories – NIO.2

The complete Java program to print all the directories under a main folder in Java using NIO.2 is provided below:

import java.nio.file.*; import java.io.IOException; class ListDirectories extends SimpleFileVisitorPath>  @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc)  System.out.println(""); // Print Name of the directory System.out.println("Directory Name: " + dir.getFileName()); // Print absolute path for the directory System.out.println("Absolute Path: " + dir.toAbsolutePath()); // Print parent directory name System.out.println("Parent Directory: " + dir.getParent().getFileName()); // continue to the next directory // Get Relative path to C: Path relative_path_to = Paths.get("C:/"); System.out.println("Relative Path: " + dir.relativize(relative_path_to)); // URI of the directory System.out.println("URI: " + dir.toUri()); return FileVisitResult.CONTINUE; > @Override public FileVisitResult visitFileFailed(Path file, IOException traversalException)  // we throw an exception if the directory cannot be accessed for any reason System.out.println(traversalException); // and continue traversing other directories return FileVisitResult.CONTINUE; > public static void main(String args[])  Path search_directory_path = Paths.get("C:/test"); //define the starting file tree ListDirectories traverser = new ListDirectories(); //instantiate the walk try  Files.walkFileTree(search_directory_path, traverser); //start the walk > catch(IOException e)  System.err.println(e); > > > 

For the input we specified above, the output of the program is shown below:

java ListDirectories Directory Name: f2 Absolute Path: C:\test\f1\f2 Parent Directory: f1 Relative Path: ..\..\.. URI: file:///C:/test/f1/f2/ Directory Name: f3 Absolute Path: C:\test\f1\f3 Parent Directory: f1 Relative Path: ..\..\.. URI: file:///C:/test/f1/f3/ Directory Name: f1 Absolute Path: C:\test\f1 Parent Directory: test Relative Path: ..\.. URI: file:///C:/test/f1/ Directory Name: f4 Absolute Path: C:\test\f4 Parent Directory: test Relative Path: ..\.. URI: file:///C:/test/f4/ Directory Name: test Absolute Path: C:\test Parent Directory: null Relative Path: .. URI: file:///C:/test/ 

which works exactly the way we wanted. We are now ready to see some advanced examples in NIO.2 to perform file traversals. We will be publishing them as we move on with the tutorial. Meanwhile, if you have any suggestions to improve the code, please post it in the comments section.

Источник

Creating and Reading Directories

Some of the methods previously discussed, such as delete , work on files, links and directories. But how do you list all the directories at the top of a file system? How do you list the contents of a directory or create a directory?

This section covers the following functionality specific to directories:

Listing a File System’s Root Directories

You can list all the root directories for a file system by using the FileSystem.getRootDirectories method. This method returns an Iterable , which enables you to use the enhanced for statement to iterate over all the root directories.

The following code snippet prints the root directories for the default file system:

Iterable dirs = FileSystems.getDefault().getRootDirectories(); for (Path name: dirs)

Creating a Directory

You can create a new directory by using the createDirectory(Path, FileAttribute) method. If you don’t specify any FileAttributes , the new directory will have default attributes. For example:

Path dir = . ; Files.createDirectory(path);

The following code snippet creates a new directory on a POSIX file system that has specific permissions:

Set perms = PosixFilePermissions.fromString("rwxr-x---"); FileAttribute attr = PosixFilePermissions.asFileAttribute(perms); Files.createDirectory(file, attr);

To create a directory several levels deep when one or more of the parent directories might not yet exist, you can use the convenience method, createDirectories(Path, FileAttribute) . As with the createDirectory(Path, FileAttribute) method, you can specify an optional set of initial file attributes. The following code snippet uses default attributes:

Files.createDirectories(Paths.get("foo/bar/test"));

The directories are created, as needed, from the top down. In the foo/bar/test example, if the foo directory does not exist, it is created. Next, the bar directory is created, if needed, and, finally, the test directory is created.

It is possible for this method to fail after creating some, but not all, of the parent directories.

Creating a Temporary Directory

You can create a temporary directory using one of createTempDirectory methods:

The first method allows the code to specify a location for the temporary directory and the second method creates a new directory in the default temporary-file directory.

Listing a Directory’s Contents

You can list all the contents of a directory by using the newDirectoryStream(Path) method. This method returns an object that implements the DirectoryStream interface. The class that implements the DirectoryStream interface also implements Iterable , so you can iterate through the directory stream, reading all of the objects. This approach scales well to very large directories.

Remember: The returned DirectoryStream is a stream. If you are not using a try- with-resources statement, don’t forget to close the stream in the finally block. The try- with-resources statement takes care of this for you.

The following code snippet shows how to print the contents of a directory:

Path dir = . ; try (DirectoryStream stream = Files.newDirectoryStream(dir)) < for (Path file: stream) < System.out.println(file.getFileName()); >> catch (IOException | DirectoryIteratorException x) < // IOException can never be thrown by the iteration. // In this snippet, it can only be thrown by newDirectoryStream. System.err.println(x); >

The Path objects returned by the iterator are the names of the entries resolved against the directory. So, if you are listing the contents of the /tmp directory, the entries are returned with the form /tmp/a , /tmp/b , and so on.

This method returns the entire contents of a directory: files, links, subdirectories, and hidden files. If you want to be more selective about the contents that are retrieved, you can use one of the other newDirectoryStream methods, as described later in this page.

Note that if there is an exception during directory iteration then DirectoryIteratorException is thrown with the IOException as the cause. Iterator methods cannot throw exception exceptions.

Filtering a Directory Listing By Using Globbing

If you want to fetch only files and subdirectories where each name matches a particular pattern, you can do so by using the newDirectoryStream(Path, String) method, which provides a built-in glob filter. If you are not familiar with glob syntax, see What Is a Glob?

For example, the following code snippet lists files relating to Java: .class, .java, and .jar files.:

Path dir = . ; try (DirectoryStream stream = Files.newDirectoryStream(dir, "*.")) < for (Path entry: stream) < System.out.println(entry.getFileName()); >> catch (IOException x) < // IOException can never be thrown by the iteration. // In this snippet, it can // only be thrown by newDirectoryStream. System.err.println(x); >

Writing Your Own Directory Filter

Perhaps you want to filter the contents of a directory based on some condition other than pattern matching. You can create your own filter by implementing the DirectoryStream.Filter interface. This interface consists of one method, accept , which determines whether a file fulfills the search requirement.

For example, the following code snippet implements a filter that retrieves only directories:

DirectoryStream.Filter filter = newDirectoryStream.Filter() < public boolean accept(Path file) throws IOException < try < return (Files.isDirectory(path)); >catch (IOException x) < // Failed to determine if it's a directory. System.err.println(x); return false; >> >;

Once the filter has been created, it can be invoked by using the newDirectoryStream(Path, DirectoryStream.Filter) method. The following code snippet uses the isDirectory filter to print only the directory’s subdirectories to standard output:

Path dir = . ; try (DirectoryStream stream = Files.newDirectoryStream(dir, filter)) < for (Path entry: stream) < System.out.println(entry.getFileName()); >> catch (IOException x)

This method is used to filter a single directory only. However, if you want to find all the subdirectories in a file tree, you would use the mechanism for Walking the File Tree.

Источник

Оцените статью