Java file find files in directory

How to find files with the file extension in Java

This article shows how to Java 8 Files.walk to walk a file tree and stream operation filter to find files that match a specific file extension from a folder and its subfolders.

 // find files matched `png` file extension from folder C:\\test try (Stream walk = Files.walk(Paths.get("C:\\test"))) < result = walk .filter(p ->!Files.isDirectory(p)) // not a directory .map(p -> p.toString().toLowerCase()) // convert path to string .filter(f -> f.endsWith("png")) // check end with .collect(Collectors.toList()); // collect all matched to a List > 

In the Files.walk method, the second argument, maxDepth defined the maximum number of directory levels to visit. And we can assign maxDepth = 1 to find files from the top-level folder only (exclude all its subfolders)

 try (Stream walk = Files.walk(Paths.get("C:\\test"), 1)) < //. >

1. Find files with a specified file extension

This example finds files matched with png file extension. The finds start at the top-level folder C:\\test and included all levels of subfolders.

 package com.mkyong.io.howto; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class FindFileByExtension1 < public static void main(String[] args) < try < Listfiles = findFiles(Paths.get("C:\\test"), "png"); files.forEach(x -> System.out.println(x)); > catch (IOException e) < e.printStackTrace(); >> public static List findFiles(Path path, String fileExtension) throws IOException < if (!Files.isDirectory(path)) < throw new IllegalArgumentException("Path must be a directory!"); >List result; try (Stream walk = Files.walk(path)) < result = walk .filter(p ->!Files.isDirectory(p)) // this is a path, not string, // this only test if path end with a certain path //.filter(p -> p.endsWith(fileExtension)) // convert path to string first .map(p -> p.toString().toLowerCase()) .filter(f -> f.endsWith(fileExtension)) .collect(Collectors.toList()); > return result; > > 
 c:\test\bk\logo-new.png c:\test\bk\resize-default.png c:\test\google.png c:\test\test1\test2\java.png . 

2. Find files with multiple file extensions

This example finds files matched with multiple file extensions ( .png , .jpg , .gif ).

 package com.mkyong.io.howto; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class FindFileByExtension2 < public static void main(String[] args) < try < String[] extensions = ; List files = findFiles(Paths.get("C:\\test"), extensions); files.forEach(x -> System.out.println(x)); > catch (IOException e) < e.printStackTrace(); >> public static List findFiles(Path path, String[] fileExtensions) throws IOException < if (!Files.isDirectory(path)) < throw new IllegalArgumentException("Path must be a directory!"); >List result; try (Stream walk = Files.walk(path, 1)) < result = walk .filter(p ->!Files.isDirectory(p)) // convert path to string .map(p -> p.toString().toLowerCase()) .filter(f -> isEndWith(f, fileExtensions)) .collect(Collectors.toList()); > return result; > private static boolean isEndWith(String file, String[] fileExtensions) < boolean result = false; for (String fileExtension : fileExtensions) < if (file.endsWith(fileExtension)) < result = true; break; >> return result; > > 
 c:\test\bk\logo-new.png c:\test\bk\resize-default.gif c:\test\bk\resize-fast.gif c:\test\bk\resize.png c:\test\google.jpg c:\test\google.png c:\test\test1\test2\java.png c:\test\test1\test2\java.jpg 

2.2 The isEndWith() method can be shorter with Java 8 stream anyMatch .

 private static boolean isEndWith(String file, String[] fileExtensions) < // Java 8, try this boolean result = Arrays.stream(fileExtensions).anyMatch(file::endsWith); return result; // old school style /*boolean result = false; for (String fileExtension : fileExtensions) < if (file.endsWith(fileExtension)) < result = true; break; >> return result;*/ > 

2.3 We also can remove the isEndWith() method and puts the anyMatch into the filter directly.

 public static List findFiles(Path path, String[] fileExtensions) throws IOException < if (!Files.isDirectory(path)) < throw new IllegalArgumentException("Path must be a directory!"); >List result; try (Stream walk = Files.walk(path, 1)) < result = walk .filter(p ->!Files.isDirectory(p)) // convert path to string .map(p -> p.toString().toLowerCase()) //.filter(f -> isEndWith(f, fileExtensions)) // lambda //.filter(f -> Arrays.stream(fileExtensions).anyMatch(ext -> f.endsWith(ext))) // method reference .filter(f -> Arrays.stream(fileExtensions).anyMatch(f::endsWith)) .collect(Collectors.toList()); > return result; > 

2.4 We can further enhance the program by passing different conditions into the stream filter ; Now, the program can easily search or find files with a specified pattern from a folder. For examples:

Читайте также:  Css div padding and margin

Find files with filename starts with «abc».

 List result; try (Stream walk = Files.walk(path)) < result = walk .filter(p ->!Files.isDirectory(p)) // convert path to string .map(p -> p.toString()) .filter(f -> f.startsWith("abc")) .collect(Collectors.toList()); > 

Find files with filename containing the words «mkyong».

 List result; try (Stream walk = Files.walk(path)) < result = walk .filter(p ->!Files.isDirectory(p)) // convert path to string .map(p -> p.toString()) .filter(f -> f.contains("mkyong")) .collect(Collectors.toList()); > 

Источник

How to Find a File in Directory in Java

Learn different ways to find a file in a given directory and sub-directories with Java. The given examples will find all files with specified file names if there are more than one files with the same name in the sub-directories.

1. Find File by Walking the Directories

The easiest and most straightforward way of finding all files in a directory or its subdirectories is walking all the files using Files.walk() method. This method traverses the directories in a depth-first manner, so files in the deep-most sub-directories are searched first.

We can optionally pass the depth of the sub-directory level to search if the directory structure is too much nested and we do not wish to go that much deeper. Note that when we close the Stream, the directory is also closed.

String fileNameToFind = "test.txt"; File rootDirectory = new File("c:/temp"); final List foundFiles = new ArrayList<>(); try (Stream walkStream = Files.walk(rootDirectory.toPath())) < walkStream.filter(p ->p.toFile().isFile()) .forEach(f -> < if (f.toString().endsWith(fileNameToFind)) < foundFiles.add(f.toFile()); >>); >

If we want to iterate over 5 levels of sub-directories then we can use the following function:

try (Stream walkStream = Files.walk(rootDirectory.toPath(), 5))

If we want to stop the search after the first file is found then we can use the Stream.findFirst() method with the stream of paths.

Optional foundFile; try (Stream walkStream = Files.walk(rootDirectory.toPath())) < foundFile = walkStream.filter(p ->p.toFile().isFile()) .filter(p -> p.toString().endsWith(fileNameToFind)) .findFirst(); > if(foundFile.isPresent()) < System.out.println(foundFile.get()); >else

Recursion is an old-fashioned way to iterate over all the files and sub-directories and apply custom logic for matching the file names. Still, we can use it if it fits our solution.

The following method findFilesByName() recursively iterates over the files and subdirectories and add the matching files into the foundFilesList.

The recursive function first lists all the files using File.listFiles() method and then iterates over them. During iteration, it further calls the listFiles() for all child directories that it checks using the file.isDirectory() method.

After the recursion ends, we can check the files found in this list.

final List foundFilesList = new ArrayList<>(); findFilesByName(rootDirectory, fileNameToFind, foundFilesList); public static void findFilesByName(File rootDir, String filenameToSearch, List foundFilesList) < Collectionfiles = List.of(rootDir.listFiles()); for (Iterator iterator = files.iterator(); iterator.hasNext(); ) < File file = (File) iterator.next(); if (file.isDirectory()) < findFilesByName(file, filenameToSearch, foundFilesList); >else if(file.getName().equalsIgnoreCase(filenameToSearch)) < foundFilesList.add(file); >> > System.out.println(foundFilesList); //Prints the found files

This short Java tutorial taught us to find a file by name in a given directory and its sub-directories. We also learned to control the search up to a configured depth of sub-directories. We used the Stream reduction method findFirst() as well if we wanted to terminate the search after the first occurrence of a matching file.

Источник

Finding Files

If you have ever used a shell script, you have most likely used pattern matching to locate files. In fact, you have probably used it extensively. If you haven’t used it, pattern matching uses special characters to create a pattern and then file names can be compared against that pattern. For example, in most shell scripts, the asterisk, * , matches any number of characters. For example, the following command lists all the files in the current directory that end in .html :

The java.nio.file package provides programmatic support for this useful feature. Each file system implementation provides a PathMatcher . You can retrieve a file system’s PathMatcher by using the getPathMatcher(String) method in the FileSystem class. The following code snippet fetches the path matcher for the default file system:

String pattern = . ; PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);

The string argument passed to getPathMatcher specifies the syntax flavor and the pattern to be matched. This example specifies glob syntax. If you are unfamiliar with glob syntax, see What is a Glob.

Glob syntax is easy to use and flexible but, if you prefer, you can also use regular expressions, or regex, syntax. For further information about regex, see the Regular Expressions lesson. Some file system implementations might support other syntaxes.

If you want to use some other form of string-based pattern matching, you can create your own PathMatcher class. The examples in this page use glob syntax.

Once you have created your PathMatcher instance, you are ready to match files against it. The PathMatcher interface has a single method, matches , that takes a Path argument and returns a boolean: It either matches the pattern, or it does not. The following code snippet looks for files that end in .java or .class and prints those files to standard output:

PathMatcher matcher = FileSystems.getDefault().getPathMatcher(«glob:*.»); Path filename = . ; if (matcher.matches(filename))

Recursive Pattern Matching

Searching for files that match a particular pattern goes hand-in-hand with walking a file tree. How many times do you know a file is somewhere on the file system, but where? Or perhaps you need to find all files in a file tree that have a particular file extension.

The Find example does precisely that. Find is similar to the UNIX find utility, but has pared down functionally. You can extend this example to include other functionality. For example, the find utility supports the -prune flag to exclude an entire subtree from the search. You could implement that functionality by returning SKIP_SUBTREE in the preVisitDirectory method. To implement the -L option, which follows symbolic links, you could use the four-argument walkFileTree method and pass in the FOLLOW_LINKS enum (but make sure that you test for circular links in the visitFile method).

To run the Find application, use the following format:

The pattern is placed inside quotation marks so any wildcards are not interpreted by the shell. For example:

Here is the source code for the Find example:

/** * Sample code that finds files that match the specified glob pattern. * For more information on what constitutes a glob pattern, see * https://docs.oracle.com/javase/tutorial/essential/io/fileOps.html#glob * * The file or directories that match the pattern are printed to * standard out. The number of matches is also printed. * * When executing this application, you must put the glob pattern * in quotes, so the shell will not expand any wild cards: * java Find . -name "*.java" */ import java.io.*; import java.nio.file.*; import java.nio.file.attribute.*; import static java.nio.file.FileVisitResult.*; import static java.nio.file.FileVisitOption.*; import java.util.*; public class Find < public static class Finder extends SimpleFileVisitor < private final PathMatcher matcher; private int numMatches = 0; Finder(String pattern) < matcher = FileSystems.getDefault() .getPathMatcher("glob:" + pattern); >// Compares the glob pattern against // the file or directory name. void find(Path file) < Path name = file.getFileName(); if (name != null && matcher.matches(name)) < numMatches++; System.out.println(file); >> // Prints the total number of // matches to standard out. void done() < System.out.println("Matched: " + numMatches); >// Invoke the pattern matching // method on each file. @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) < find(file); return CONTINUE; >// Invoke the pattern matching // method on each directory. @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) < find(dir); return CONTINUE; >@Override public FileVisitResult visitFileFailed(Path file, IOException exc) < System.err.println(exc); return CONTINUE; >> static void usage() < System.err.println("java Find " + " -name \"\""); System.exit(-1); > public static void main(String[] args) throws IOException < if (args.length < 3 || !args[1].equals("-name")) usage(); Path startingDir = Paths.get(args[0]); String pattern = args[2]; Finder finder = new Finder(pattern); Files.walkFileTree(startingDir, finder); finder.done(); >>

Recursively walking a file tree is covered in Walking the File Tree.

Источник

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