This is supposed to be simple, but I can\'t get it - \"Write a program that searches for a particular file name in a given directory.\" I\'ve found a few examples of a hardc
you can try something like this:
import java.io.*;
import java.util.*;
class FindFile
{
public void findFile(String name,File file)
{
File[] list = file.listFiles();
if(list!=null)
for (File fil : list)
{
if (fil.isDirectory())
{
findFile(name,fil);
}
else if (name.equalsIgnoreCase(fil.getName()))
{
System.out.println(fil.getParentFile());
}
}
}
public static void main(String[] args)
{
FindFile ff = new FindFile();
Scanner scan = new Scanner(System.in);
System.out.println("Enter the file to be searched.. " );
String name = scan.next();
System.out.println("Enter the directory where to search ");
String directory = scan.next();
ff.findFile(name,new File(directory));
}
}
Here is the output:
J:\Java\misc\load>java FindFile
Enter the file to be searched..
FindFile.java
Enter the directory where to search
j:\java\
FindFile.java Found in->j:\java\misc\load
Using Java 8+ features we can write the code in few lines:
protected static Collection<Path> find(String fileName, String searchDirectory) throws IOException {
try (Stream<Path> files = Files.walk(Paths.get(searchDirectory))) {
return files
.filter(f -> f.getFileName().toString().equals(fileName))
.collect(Collectors.toList());
}
}
Files.walk
returns a Stream<Path>
which is "walking the file tree rooted at" the given searchDirectory
. To select the desired files only a filter is applied on the Stream
files
. It compares the file name of a Path
with the given fileName
.
Note that the documentation of Files.walk
requires
This method must be used within a try-with-resources statement or similar control structure to ensure that the stream's open directories are closed promptly after the stream's operations have completed.
I'm using the try-resource-statement.
For advanced searches an alternative is to use a PathMatcher
:
protected static Collection<Path> find(String searchDirectory, PathMatcher matcher) throws IOException {
try (Stream<Path> files = Files.walk(Paths.get(searchDirectory))) {
return files
.filter(matcher::matches)
.collect(Collectors.toList());
}
}
An example how to use it to find a certain file:
public static void main(String[] args) throws IOException {
String searchDirectory = args[0];
String fileName = args[1];
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("regex:.*" + fileName);
Collection<Path> find = find(searchDirectory, matcher);
System.out.println(find);
}
More about it: Oracle Finding Files tutorial
This method will recursively search thru each directory starting at the root, until the fileName is found, or all remaining results come back null.
public static String searchDirForFile(String dir, String fileName) {
File[] files = new File(dir).listFiles();
for(File f:files) {
if(f.isDirectory()) {
String loc = searchDirForFile(f.getPath(), fileName);
if(loc != null)
return loc;
}
if(f.getName().equals(fileName))
return f.getPath();
}
return null;
}
With **Java 8* there is an alternative that use streams and lambdas:
public static void recursiveFind(Path path, Consumer<Path> c) {
try (DirectoryStream<Path> newDirectoryStream = Files.newDirectoryStream(path)) {
StreamSupport.stream(newDirectoryStream.spliterator(), false)
.peek(p -> {
c.accept(p);
if (p.toFile()
.isDirectory()) {
recursiveFind(p, c);
}
})
.collect(Collectors.toList());
} catch (IOException e) {
e.printStackTrace();
}
}
So this will print all the files recursively:
recursiveFind(Paths.get("."), System.out::println);
And this will search for a file:
recursiveFind(Paths.get("."), p -> {
if (p.toFile().getName().toString().equals("src")) {
System.out.println(p);
}
});
If you want to use a dynamic filename filter you can implement FilenameFilter and pass in the constructor the dynamic name.
Of course this implies taht you must instantiate every time the class (overhead), but it works
Example:
public class DynamicFileNameFilter implements FilenameFilter {
private String comparingname;
public DynamicFileNameFilter(String comparingName){
this.comparingname = comparingName;
}
@Override
public boolean accept(File dir, String name) {
File file = new File(name);
if (name.equals(comparingname) && !file.isDirectory())
return false;
else
return true;
}
}
then you use where you need:
FilenameFilter fileNameFilter = new DynamicFileNameFilter("thedynamicNameorpatternYouAreSearchinfor");
File[] matchingFiles = dir.listFiles(fileNameFilter);
The Following code helps to search for a file in directory and open its location
import java.io.*;
import java.util.*;
import java.awt.Desktop;
public class Filesearch2 {
public static void main(String[] args)throws IOException {
Filesearch2 fs = new Filesearch2();
Scanner scan = new Scanner(System.in);
System.out.println("Enter the file to be searched.. " );
String name = scan.next();
System.out.println("Enter the directory where to search ");
String directory = scan.next();
fs.findFile(name,new File(directory));
}
public void findFile(String name,File file1)throws IOException
{
File[] list = file1.listFiles();
if(list!=null)
{
for(File file2 : list)
{
if (file2.isDirectory())
{
findFile(name,file2);
}
else if (name.equalsIgnoreCase(file2.getName()))
{
System.out.println("Found");
System.out.println("File found at : "+file2.getParentFile());
System.out.println("Path diectory: "+file2.getAbsolutePath());
String p1 = ""+file2.getParentFile();
File f2 = new File(p1);
Desktop.getDesktop().open(f2);
}
}
}
}
}