Find files in a folder using Java
So if the file starts with temp and has an extension .txt I would like to then put that file name into a File file = new File(«C:/example/temp***.txt); so I can then read in the file, the loop then needs to move onto the next file to check to see if it meets as above.
13 Answers 13
That will give you a list of the files in the directory you want that match a certain filter.
The code will look similar to:
// your directory File f = new File("C:\\example"); File[] matchingFiles = f.listFiles(new FilenameFilter() < public boolean accept(File dir, String name) < return name.startsWith("temp") && name.endsWith("txt"); >>);
BTW Java can handle slash ( / ) just fine under Windows. So there’s no need for backslash (and escaping it).
If you’re under Java 7, you could/should use java.nio.FileSystems.getDefault().getPath(String dir1, String dir2, . ) to concatenate directories/files in a truly «multiplatform way»
File dir = new File(directory); File[] matches = dir.listFiles(new FilenameFilter() < public boolean accept(File dir, String name) < return name.startsWith("temp") && name.endsWith(".txt"); >>);
+1 for having slightly more pleasing variable names than the nearly identical code posted 2 minutes before yours.
@Null Set, that answer was written while I was writing mine, so it’s not like I copied what Justin wrote and re-named the variables. 🙂 Thanks for the up-vote, though.
I know, this is an old question. But just for the sake of completeness, the lambda version.
File dir = new File(directory); File[] files = dir.listFiles((dir1, name) -> name.startsWith("temp") && name.endsWith(".txt"));
Have a look at java.io.File.list() and FilenameFilter .
As @Clarke said, you can use java.io.FilenameFilter to filter the file by specific condition.
As a complementary, I’d like to show how to use java.io.FilenameFilter to search file in current directory and its subdirectory.
The common methods getTargetFiles and printFiles are used to search files and print them.
public class SearchFiles < //It's used in dfs private Mapmap = new HashMap(); private File root; public SearchFiles(File root) < this.root = root; >/** * List eligible files on current path * @param directory * The directory to be searched * @return * Eligible files */ private String[] getTargetFiles(File directory) < if(directory == null)< return null; >String[] files = directory.list(new FilenameFilter() < @Override public boolean accept(File dir, String name) < // TODO Auto-generated method stub return name.startsWith("Temp") && name.endsWith(".txt"); >>); return files; > /** * Print all eligible files */ private void printFiles(String[] targets) < for(String target: targets)< System.out.println(target); >> >
I will demo how to use recursive, bfs and dfs to get the job done.
/** * How many files in the parent directory and its subdirectory
* depends on how many files in each subdirectory and their subdirectory */ private void recursive(File path) < printFiles(getTargetFiles(path)); for(File file: path.listFiles())< if(file.isDirectory())< recursive(file); >> if(path.isDirectory()) < printFiles(getTargetFiles(path)); >> public static void main(String args[])
Breadth First Search:
/** * Search the node's neighbors firstly before moving to the next level neighbors */ private void bfs() < if(root == null)< return; >Queue queue = new LinkedList(); queue.add(root); while(!queue.isEmpty()) < File node = queue.remove(); printFiles(getTargetFiles(node)); File[] childs = node.listFiles(new FileFilter()< @Override public boolean accept(File pathname) < // TODO Auto-generated method stub if(pathname.isDirectory()) return true; return false; >>); if(childs != null) < for(File child: childs)< queue.add(child); >> > > public static void main(String args[])
Depth First Search:
/** * Search as far as possible along each branch before backtracking */ private void dfs() < if(root == null)< return; >Stack stack = new Stack(); stack.push(root); map.put(root.getAbsolutePath(), true); while(!stack.isEmpty())< File node = stack.peek(); File child = getUnvisitedChild(node); if(child != null)< stack.push(child); printFiles(getTargetFiles(child)); map.put(child.getAbsolutePath(), true); >else < stack.pop(); >> > /** * Get unvisited node of the node * */ private File getUnvisitedChild(File node) < File[] childs = node.listFiles(new FileFilter()< @Override public boolean accept(File pathname) < // TODO Auto-generated method stub if(pathname.isDirectory()) return true; return false; >>); if(childs == null) < return null; >for(File child: childs) < if(map.containsKey(child.getAbsolutePath()) == false)< map.put(child.getAbsolutePath(), false); >if(map.get(child.getAbsolutePath()) == false) < return child; >> return null; > public static void main(String args[])
For list out Json files from your given directory.
import java.io.File; import java.io.FilenameFilter; public class ListOutFilesInDir < public static void main(String[] args) throws Exception < File[] fileList = getFileList("directory path"); for(File file : fileList) < System.out.println(file.getName()); >> private static File[] getFileList(String dirPath) < File dir = new File(dirPath); File[] fileList = dir.listFiles(new FilenameFilter() < public boolean accept(File dir, String name) < return name.endsWith(".json"); >>); return fileList; > >
Appache commons IO various
See Apache javadoc here. It matches the wildcard with the filename. So you can use this method for your comparisons.
My reputation does not allow me to add comment. The only way I could contribute is to add another answer. I edited my original post to add more details.
Consider Apache Commons IO, it has a class called FileUtils that has a listFiles method that might be very useful in your case.
Path dir = Paths.get("path/to/search"); String prefix = "prefix"; Files.find(dir, 3, (path, attributes) -> path.getFileName().toString().startsWith(prefix)) .forEach(path -> log.info("Path = " + path.toString()));
To elaborate on this response, Apache IO Utils might save you some time. Consider the following example that will recursively search for a file of a given name:
File file = FileUtils.listFiles(new File("the/desired/root/path"), new NameFileFilter("filename.ext"), FileFilterUtils.trueFileFilter() ).iterator().next();
As of Java 1.8, you can use Files.list to get a stream:
Path findFile(Path targetDir, String fileName) throws IOException < return Files.list(targetDir).filter( (p) -> < if (Files.isRegularFile(p)) < return p.getFileName().toString().equals(fileName); >else < return false; >>).findFirst().orElse(null); >
You give the name of your file, the path of the directory to search, and let it make the job.
private static String getPath(String drl, String whereIAm) < File dir = new File(whereIAm); //StaticMethods.currentPath() + "\\src\\main\\resources\\" + for(File e : dir.listFiles()) < if(e.isFile() && e.getName().equals(drl)) if(e.isDirectory()) < String idiot = getPath(drl, e.getPath()); if(idiot != null) > > return null; >
- Matcher.find and Files.walk methods could be an option to search files in more flexible way
- String.format combines regular expressions to create search restrictions
- Files.isRegularFile checks if a path is’t directory, symbolic link, etc.
//Searches file names (start with "temp" and extension ".txt") //in the current directory and subdirectories recursively Path initialPath = Paths.get("."); PathUtils.searchRegularFilesStartsWith(initialPath, "temp", ".txt"). stream().forEach(System.out::println);
public final class PathUtils < private static final String startsWithRegex = "(?\\d\\[\\]\\(\\) ])"; private static final String endsWithRegex = "(?=[\\.\\n])"; private static final String containsRegex = "%s(?:[^\\/\\\\]*(?=((?i)%s(. ))))"; public static List searchRegularFilesStartsWith(final Path initialPath, final String fileName, final String fileExt) throws IOException < return searchRegularFiles(initialPath, startsWithRegex + fileName, fileExt); >public static List searchRegularFilesEndsWith(final Path initialPath, final String fileName, final String fileExt) throws IOException < return searchRegularFiles(initialPath, fileName + endsWithRegex, fileExt); >public static List searchRegularFilesAll(final Path initialPath) throws IOException < return searchRegularFiles(initialPath, "", ""); >public static List searchRegularFiles(final Path initialPath, final String fileName, final String fileExt) throws IOException < final String regex = String.format(containsRegex, fileName, fileExt); final Pattern pattern = Pattern.compile(regex); try (Streamwalk = Files.walk(initialPath.toRealPath())) < return walk.filter(path ->Files.isRegularFile(path) && pattern.matcher(path.toString()).find()) .collect(Collectors.toList()); > > private PathUtils() < >>
Try startsWith regex for \txt\temp\tempZERO0.txt:
Try endsWith regex for \txt\temp\ZERO0temp.txt:
Try contains regex for \txt\temp\tempZERO0tempZERO0temp.txt:
Поиск файла на компьютере
Изучая работу класса File , стало интересно, есть ли у класса File какой-то метод для поиска файла на компьютере, если известно только имя файла и расширение?
@AntonSorokin Да, спасибо большое, ваш пример с сайта pastebin — единственный, в котором смог разобраться)
3 ответа 3
private static File findFile(File dir, String name) < File result = null; // no need to store result as String, you're returning File anyway File[] dirlist = dir.listFiles(); for(int i = 0; i < dirlist.length; i++) < if(dirlist[i].isDirectory()) < result = findFile(dirlist[i], name); if (result!=null) break; // recursive call found the file; terminate the loop >else if(dirlist[i].getName().matches(name)) < return dirlist[i]; // found the file; return it >> return result; // will return null if we didn't find anything >
Используя API файлов Java 8:
public static File searchFileJava8(final String rootFolder, final String fileName) < File target = null; Path root = Paths.get(rootFolder); try (Streamstream = Files.find(root, Integer.MAX_VALUE, (path, attr) -> path.getFileName().toString().equals(fileName))) < Optionalpath = stream.findFirst(); if(path.isPresent()) < target = path.get().toFile(); >> catch (IOException e) < >return target; >
Либо, поиск глубиной(самое быстрое решение):
public static File searchFileByDeepness(final String directoryName, final String fileName) < File target = null; if(directoryName != null && fileName != null) < File directory = new File(directoryName); if(directory.isDirectory()) < File file = new File(directoryName, fileName); if(file.isFile()) < target = file; >else < ListsubDirectories = getSubDirectories(directory); do < ListsubSubDirectories = new ArrayList(); for(File subDirectory : subDirectories) < File fileInSubDirectory = new File(subDirectory, fileName); if(fileInSubDirectory.isFile()) < return fileInSubDirectory; >subSubDirectories.addAll(getSubDirectories(subDirectory)); > subDirectories = subSubDirectories; > while(subDirectories != null && ! subDirectories.isEmpty()); > > > return target; > private static List getSubDirectories(final File directory) < File[] subDirectories = directory.listFiles(new FilenameFilter() < @Override public boolean accept(final File current, final String name) < return new File(current, name).isDirectory(); >>); return Arrays.asList(subDirectories); >
Scanner input = new Scanner(System.in); File f; String path, file; boolean result = false; System.out.println("Enter the required path for search: "); path = input.nextLine(); f = new File(path+"."); System.out.println("Enter the name of required file: "); file = input.nextLine(); File[] files = f.listFiles(); for(int i = 0; i < files.length; i++) if(files[i].toString().equals(path+".\\"+file) && files[i].isFile())< result = true; break; >if(result == true) System.out.println("File located in the folder"); else System.out.println("File was not found ");
Выбирайте то, что вам более удобно.
Java: Find .txt files in specified folder
You can use the listFiles() method provided by the java.io.File class.
import java.io.File; import java.io.FilenameFilter; public class Filter < public File[] finder( String dirName)< File dir = new File(dirName); return dir.listFiles(new FilenameFilter() < public boolean accept(File dir, String filename) < return filename.endsWith(".txt"); >> ); > >
@Funsuk, this works for me just fine, at least for the simple test cases I’ve tried. 36 people seem to agree. In what way does it not work for you?
List textFiles(String directory) < ListtextFiles = new ArrayList(); File dir = new File(directory); for (File file : dir.listFiles()) < if (file.getName().endsWith((".txt"))) < textFiles.add(file.getName()); >> return textFiles; >
You want to do a case insensitive search in which case:
if (file.getName().toLowerCase().endsWith((".txt")))
If you want to recursively search for through a directory tree for text files, you should be able to adapt the above as either a recursive function or an iterative function using a stack.
import org.apache.commons.io.filefilter.WildcardFileFilter; . . File dir = new File(fileDir); FileFilter fileFilter = new WildcardFileFilter("*.txt"); File[] files = dir.listFiles(fileFilter);
The code above works great for me
It's really useful, I used it with a slight change:
filename=directory.list(new FilenameFilter() < public boolean accept(File dir, String filename) < return filename.startsWith(ipro); >>);
I made my solution based on the posts I found here with Google. And I thought there is no harm to post mine as well even if it is an old thread.
The only plus this code gives is that it can iterate through sub-directories as well.
import java.io.File; import java.io.FileFilter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.commons.io.filefilter.DirectoryFileFilter; import org.apache.commons.io.filefilter.WildcardFileFilter;
List exploreThis(String dirPath) < File topDir = new File(dirPath); Listdirectories = new ArrayList<>(); directories.add(topDir); List textFiles = new ArrayList<>(); List filterWildcards = new ArrayList<>(); filterWildcards.add("*.txt"); filterWildcards.add("*.doc"); FileFilter typeFilter = new WildcardFileFilter(filterWildcards); while (directories.isEmpty() == false) < ListsubDirectories = new ArrayList(); for(File f : directories) < subDirectories.addAll(Arrays.asList(f.listFiles((FileFilter)DirectoryFileFilter.INSTANCE))); textFiles.addAll(Arrays.asList(f.listFiles(typeFilter))); >directories.clear(); directories.addAll(subDirectories); > return textFiles; >
Java NIO Search file in a directory
I want to search a file(without knowing the full name) in a specific directory using Java NIO and glob.
public static void match(String glob, String location) throws IOException < final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher( glob); Files.walkFileTree(Paths.get(location), new SimpleFileVisitor() < @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException < if (pathMatcher.matches(path)) < System.out.println(path); >return FileVisitResult.CONTINUE; > >); >
Reading some tutorial I did this. I just want to return string if I find(first) file with given glob String.
if (pathMatcher.matches(path))
4 Answers 4
There are two things to be changed:
To "find(first) file with given glob String" you need to finish walking the tree if you encounter the file, thus if a match is given. And you need to store the matching path as result. The result of Files.walkFileTree itself is the "the starting file" (JavaDoc). That's a Path pointing to the location .
public static String match(String glob, String location) throws IOException < StringBuilder result = new StringBuilder(); PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(glob); Files.walkFileTree(Paths.get(location), new SimpleFileVisitor() < @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException < if (pathMatcher.matches(path)) < result.append(path.toString()); return FileVisitResult.TERMINATE; >return FileVisitResult.CONTINUE; > >); return result.toString(); >
If there is no match then the resulting String is empty.
EDIT:
Using Files.walk we can implement the search with less code still using a glob expression based matcher:
public static Optional match(String glob, String location) throws IOException
The Optional as result shows that there may be no match.
Do you think this would be more readable? Is this because you prefer return null instead of an empty String if no result is found?
Or try(Stream stream = Files.find(Paths.get(location), Integer.MAX_VALUE, (path,attr) -> pathMatcher.matches(path)))
Based on your own code. Just stop traversing once found some match
public class Main < private static Path found = "nothing"; // First file found public static void main(String[] args) throws IOException < String glob = "glob:**."; //pattern to look for String location = "D:\\"; //where to search match(location, glob); System.out.println("Found: " + found); > public static void match(String location, String glob) throws IOException < final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher(glob); Files.walkFileTree(Paths.get(location), new SimpleFileVisitor() < @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException < if (pathMatcher.matches(path)) < found = path; // Match found, stop traversal return FileVisitResult.TERMINATE; >return FileVisitResult.CONTINUE; > >); > >
Or you can populate collection saving all the files matching the pattern
I'm not sure what you expect to do but I'd avoid mixing the syntax with wildcards. I just tested it under bash and the inner wildcard isn't expanded but rather understood as a literal * . I haven't tested with Java so it might just work, but you'd be at least sure to confuse people familiar with linux
@Aaron used it to look for properties in Windows. Not sure about bash but you are right, better to edit to avoid potential troubles
Also, the OP wants to return a string. Could you put the found in the match method and return it at the end of the method, making the void -returning method a Path -returning method?
I don't know if this example could help you further, but it seems like you would need your own custom file visitor. Here is an alternative solution:
package com.jesperancinha.files; import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; import java.nio.file.Path; import java.nio.file.PathMatcher; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; public class GlobFileVisitor extends SimpleFileVisitor < private final PathMatcher pathMatcher; private Path path; public GlobFileVisitor(String glob) < this.pathMatcher = FileSystems.getDefault().getPathMatcher(glob); >@Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) < if (pathMatcher.matches(path)) < this.path = path; return FileVisitResult.TERMINATE; >return FileVisitResult.CONTINUE; > public Path getFoundPath() < return path; >>
And this is another possibility for your running example:
package com.jesperancinha.files; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class FileFinder < public static void main(String[] args) throws IOException < String glob = "glob:**."; String location = "/Users/joao/dev/src/jesperancinha"; Path found = match(location, glob); System.out.println("Found: " + found); > public static Path match(String location, String glob) throws IOException < GlobFileVisitor globFileVisitor = new GlobFileVisitor(glob); Files.walkFileTree(Paths.get(location), globFileVisitor); return globFileVisitor.getFoundPath(); >>