The Files class provides a method- newDirectoryStream to get the Directory contents for a give path instance. There are other overloaded versions of newDirectoryStream method which take in filters to apply on the directory content.
also read:
Listing all files in the directory
Using Files.newDirectoryStream method gives an instance of DirectoryStream class which is a Iterable i.e one can get iterate over its contents. Also it implements AutoCloseable, Closeable which means that one can make use of try with resources to close the directory stream after use.
Path basePath = Paths.get("D:/tests"); // Listing the files in the directory System.out.println("All files:"); try (DirectoryStream<Path> pathList = Files.newDirectoryStream(basePath)) { for (Path path : pathList) { System.out.println(path.toString()); } } catch (IOException e) { e.printStackTrace(); }
Output:
All files: D:\tests\another_test.txt D:\tests\DirectoryFilterTest.class D:\tests\somDoc.docx D:\tests\test1.txt
Applying Filter using GLOB pattern
In the above sample we listed all the files, we can even use regular expression strings to restrict the files to be obtained from the directory. This regular expression structure is called as a GLOB pattern. Some rules for Glob pattern are:
- * represents any number of characters
- ? represents a single character
- {} represents a collection of patterns like {txt,doc}
- [] represents a set of single characters like [A-Z], [0-9]
Using the Glob pattern we would restrict to fetch only the txt files
try (DirectoryStream<Path> pathList = Files.newDirectoryStream(basePath,"*.txt")) { for (Path path : pathList) { System.out.println(path.toString()); } } catch (IOException e) { e.printStackTrace(); }
Output:
All text files[Using Glob pattern]: D:\tests\another_test.txt D:\tests\test1.txt
Applying filter using the DirectoryStream.Filter class
Another approach to apply filter is to extend the DirectoryStream.Filter class and overrides its accept(Path) method. The paths for which the accept(Path) method returns true would be fetched and listed.
The same example above implemented using DirectoryStream.Filter:
System.out.println("All document files[Using Filter class]"); DirectoryStream.Filter<Path> documentFilter = new DirectoryStream.Filter<Path>() { @Override public boolean accept(Path entry) throws IOException { String fileName = entry.getFileName().toString(); return fileName != null && fileName.endsWith("txt"); } }; try (DirectoryStream<Path> pathList = Files.newDirectoryStream(basePath, documentFilter)) { for (Path path : pathList) { System.out.println(path.toString()); } } catch (IOException e) { e.printStackTrace(); }
Output:
All document files[Using Filter class] D:\tests\another_test.txt D:\tests\test1.txt
Its clear that for filtering based on file names glob patterns is the preferred approach and for filtering based on other parameters like file size, file attributes using DirectoryStream.Filter is the better approach.
The complete code for this can be found here.