public static String getAdobeExePath(String basePath, String exeName) < File[] files = new File(basePath).listFiles(); String foundPath; for (int i = 0; i < files.length; i++) < if (files[i].isDirectory()) < foundPath = getAdobeExePath(files[i].getAbsolutePath(), exeName); if (foundPath != null) < return foundPath; >>else < if (exeName.equals(files[i].getName())) < return files[i].getAbsolutePath(); >> > return null; >
I did a little more down drill on the problem and found a way to do this in a synchronised manner using ForkJoinPool as follows:
import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveTask; import java.util.concurrent.TimeUnit; public class ForkJoinFolderProcessor < public static void main(String[] args) < ForkJoinPool pool = new ForkJoinPool(); MyFolderProcessor hadoop = new MyFolderProcessor("/Users/*****/backups/h/", "log"); MyFolderProcessor t8 = new MyFolderProcessor("/Users/*******/apache-tomcat-9.0.2", "log"); MyFolderProcessor t9 = new MyFolderProcessor("/Users/******/apache-tomcat-8.5.20", "log"); pool.execute(hadoop); pool.execute(t8); pool.execute(t9); do < System.out.println("---------------------"); System.out.println("Parallelism : "+pool.getParallelism()); System.out.println("Active Threads : "+pool.getActiveThreadCount()); System.out.println("Task Count : "+pool.getQueuedTaskCount()); System.out.println("Steal Count : "+pool.getStealCount()); System.out.println("---------------------"); try < TimeUnit.SECONDS.sleep(1); >catch (InterruptedException e) < e.printStackTrace(); >>while((!hadoop.isDone()) || (!t8.isDone()) || (!t9.isDone())); pool.shutdown(); List results = hadoop.join(); System.out.println("Hadoop: Files found : " + results.size()+" "+results.toString()); results = t8.join(); System.out.println("T8: Files found : " + results.size()+" "+results.toString()); results = t9.join(); System.out.println("T9: Files found : " + results.size()+" "+results.toString()); > > class MyFolderProcessor extends RecursiveTask < private static final long serialVersionUID = 1L; private final String filepath; private final String fileExt; public MyFolderProcessor(String path, String extension) < this.filepath = path; this.fileExt = extension; >@Override protected List compute() < Listlist = new ArrayList(); List tasks = new ArrayList(); File file = new File(filepath); File content[] = file.listFiles(); if(content != null) < for(File f : content) < if(f.isDirectory()) < MyFolderProcessor task = new MyFolderProcessor(f.getAbsolutePath(), fileExt); task.fork(); tasks.add(task); >else < if(checkFile(f.getName())) list.add(f.getAbsolutePath()); >> > if (tasks.size() > 50) < System.out.println("tasks ran."+ file.getAbsolutePath()+" "+ tasks.size()); >addResultsFromTasks(list, tasks); return list; > private void addResultsFromTasks(List list, List tasks) < for (MyFolderProcessor item : tasks) < list.addAll(item.join()); >> private boolean checkFile(String name) < return name.endsWith(fileExt); >>
Though it is more complex solution, but it works pretty well in case of multi threaded environment.
Источник
Recursively search for a directory in Java
What is the best way to find a directory with a specific name in Java? The directory that I am looking for can be located either in the current directory or one of its subdirectories.
What have you tried? Or rather, what are your theories based on testing the best 2 (shrugs) approaches you could think of? Or does this question actually mean "Can u giv me teh codez?"?
7 Answers 7
Optional hit = Files.walk(myPath) .filter(file -> file.getFileName().equals(myName)) .findAny();
The #walk is lazy, so any short-circuiting terminal operation will optimize the IO required.
That compares java.nio.Path from Path.getFileName with String . I suggest file.getFileName().toFile.getName() knowing that this seems complicated, maybe expensive.
To walk the file tree, FileVisitor interface can be used. Please see the tutorial. Please see Find sample codes also.
This is a better solution than @MadcoreTom's #listFiles as it lets you terminate the walk once the file is found.
Your solution will include the use of File.listFiles(String)
As you mentioned recursion should cater to this requirement
import java.io.File; public class CheckFile < private static boolean foundFolder = false; public static void main(String[] args) < File dir = new File("currentdirectory"); findDirectory(dir); >private static void findDirectory(File parentDirectory) < if(foundFolder) < return; >File[] files = parentDirectory.listFiles(); for (File file : files) < if (file.isFile()) < continue; >if (file.getName().equals("folderNameToFind")) < foundFolder = true; break; >if(file.isDirectory()) < findDirectory(file); >> > >
Am I correct that this method is not reusable (moving it to some utility class will not work) i.e. It can detect folder only once and once detected 'foundFolder' will remain to be true?
public static final File findIt(File rootDir, String fileName) < File[] files = rootDir.listFiles(); Listdirectories = new ArrayList(files.length); for (File file : files) < if (file.getName().equals(fileName)) < return file; >else if (file.isDirectory()) < directories.add(file); >> for (File directory : directories) < File file = findIt(directory); if (file != null) < return file; >> return null; >
Divide and conquer? A naive approach: For every directory, you may start a task, it does the following:
- list every directory
- if the list contains a matching directory, prints and exit the application
- start a task for every directory.
Or, you should use the concept of Recursively search the file until it found: Here is the Code:
String name; //to hold the search file name public String listFolder(File dir) < int flag; File[] subDirs = dir.listFiles(new FileFilter() < @Override public boolean accept(File pathname) < return pathname.isDirectory(); >>); System.out.println("File of Directory: " + dir.getAbsolutePath()); flag = Listfile(dir); if (flag == 0) < System.out.println("File Found in THe Directory: " + dir.getAbsolutePath()); Speak("File Found in THe Directory: !!" + dir.getAbsolutePath()); return dir.getAbsolutePath(); >for (File folder : subDirs) < listFolder(folder); >return null; > private int Listfile(File dir) < boolean ch = false; File[] files = dir.listFiles(); for (File file : files) < Listfile(file); if (file.getName().indexOf(name.toLowerCase()) != -1)/check all in lower case System.out.println(name + "Found Sucessfully!!"); ch = true; > > if (ch) < return 1; >else < return 0; >>
Источник
How to read files recursively in Java 7?
I know of the Apache Commons IO library for file directory processing in Java. However, List all files from a directory recursively with Java talks about native support in Java 7. Does anyone have experience on how to recursively list/read files in a directory using Java 7?
2 Answers 2
There's a tutorial on it. Basically you implement a Visitor which can then be called as directories are entered, exited, and files are encountered. There is support for determining if files are symbolic links, and options to follow the symbolic link (if you care to do so). A quick read on what Java Path s are might be useful, and the entire documentation starts here.
import static java.nio.file.FileVisitResult.*; public static class PrintFiles extends SimpleFileVisitor < // Print information about // each type of file. @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attr) < if (attr.isSymbolicLink()) < System.out.format("Symbolic link: %s ", file); >else if (attr.isRegularFile()) < System.out.format("Regular file: %s ", file); >else < System.out.format("Other: %s ", file); >System.out.println("(" + attr.size() + "bytes)"); return CONTINUE; > // Print each directory visited. @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) < System.out.format("Directory: %s%n", dir); return CONTINUE; >// If there is some error accessing // the file, let the user know. // If you don't override this method // and an error occurs, an IOException // is thrown. @Override public FileVisitResult visitFileFailed(Path file, IOException exc) < System.err.println(exc); return CONTINUE; >>
A second example (from the Java implementation of find ) that illustrates file walking could be easily modified to "match" all files.
/* * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Oracle or the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 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.*; /** * Sample code that finds files that * match the specified glob pattern. * For more information on what * constitutes a glob pattern, see * http://docs.oracle.com/javase/javatutorials/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" */ public class Find < /** * A that finds * all files that match the * specified pattern. */ 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(); >>
On my system (Linux / Fedora), it worked well; however, I was only testing it for functionality, and playing around with it. I didn't stress test it for performance or any other meaningful measurement (beyond "it works").
Источник