web-dev-qa-db-fra.com

Java - Rechercher des fichiers dans un répertoire

C’est censé être simple, mais je ne peux pas l’obtenir - "Ecrivez un programme qui recherche un nom de fichier particulier dans un répertoire donné." J'ai trouvé quelques exemples de nom de fichier et de répertoire codés en dur, mais j'ai besoin que le nom de répertoire et le nom de fichier soient saisis par l'utilisateur.

public static void main(String[] args) {
    String fileName = args[0]; // For the filename declaration
    String directory;     
    boolean found;

    File dir = new File(directory);

    File[] matchingFiles = dir.listFiles(new FilenameFilter() {
        public boolean accept(File dir, String fileName) {
            return true;
        }
    });

}
10
A C

vous pouvez essayer quelque chose comme ceci:

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));
    }
}

Voici la sortie:

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
25
Vishal K

Avec ** Java 8 *, il existe une alternative qui utilise les flux et les 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();
  }
}

Donc, cela va imprimer tous les fichiers de manière récursive:

recursiveFind(Paths.get("."), System.out::println);

Et cela va chercher un fichier:

recursiveFind(Paths.get("."), p -> { 
  if (p.toFile().getName().toString().equals("src")) {
    System.out.println(p);
  }
});
1
freedev

Cela ressemble à une question de devoirs, alors je vais vous donner quelques indications:

Essayez de donner de bons noms de variables distinctifs. Ici, vous avez d'abord utilisé "NomFichier" pour le répertoire, puis pour le fichier. C'est déroutant et ne vous aidera pas à résoudre le problème. Utilisez des noms différents pour différentes choses.

Vous n'utilisez pas Scanner pour rien, et ce n'est pas nécessaire ici, éliminez-le.

De plus, la méthode accept devrait renvoyer une valeur booléenne. En ce moment, vous essayez de retourner une chaîne. Boolean signifie qu'il doit renvoyer true ou false. Par exemple, return a > 0; peut renvoyer true ou false, selon la valeur de a. Mais return fileName; renverra simplement la valeur de fileName, qui est une chaîne.

1
amarillion

Si vous souhaitez utiliser un filtre de nom de fichier dynamique, vous pouvez implémenter FilenameFilter et transmettre le nom dynamique au constructeur.

Bien sûr, cela implique que vous deviez instancier à chaque fois la classe (overhead), mais cela fonctionne

Exemple: 

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;
    }

}

alors vous utilisez où vous avez besoin:

FilenameFilter fileNameFilter = new DynamicFileNameFilter("thedynamicNameorpatternYouAreSearchinfor");
File[] matchingFiles = dir.listFiles(fileNameFilter);
1
Juan

Le code suivant permet de rechercher un fichier dans le répertoire et d’ouvrir son emplacement.

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);                               
            }                      
        }        
      }
    }        
}
0
Mr. J

J'ai utilisé une approche différente pour rechercher un fichier à l'aide de la pile .. en gardant à l'esprit qu'il pourrait y avoir des dossiers dans un dossier. Bien que sa recherche ne soit pas plus rapide que celle de Windows (et je ne m'y attendais pas), elle donne un résultat correct. Veuillez modifier le code comme vous le souhaitez. Ce code a été créé à l’origine pour extraire le chemin du fichier de certaines extensions de fichiers :). N'hésitez pas à optimiser.

import Java.io.File;
import Java.io.IOException;
import Java.util.ArrayList;
import Java.util.List;

/**
 * @author Deepankar Sinha
 */
public class GetList {
    public List<String> stack;
    static List<String> lnkFile;
    static List<String> progName;

    int index=-1;
    public static void main(String args[]) throws IOException
    {

        //var-- progFile:Location of the file to be search. 
        String progFile="C:\\";
        GetList obj=new GetList();
        String temp=progFile;
        int i;
        while(!"&%@#".equals(temp))
        {
            File dir=new File(temp);
            String[] directory=dir.list();
            if(directory!=null){
            for(String name: directory)
            {
                if(new File(temp+name).isDirectory())
                    obj.Push(temp+name+"\\");
                else
                    if(new File(temp+name).isFile())
                    {
                        try{
                            //".exe can be replaced with file name to be searched. Just exclude name.substring()... you know what to do.:)
                        if(".exe".equals(name.substring(name.lastIndexOf('.'), name.length())))
                        {
                            //obj.addFile(temp+name,name);
                            System.out.println(temp+name);
                        }
                        }catch(StringIndexOutOfBoundsException e)
                        {
                            //debug purpose
                            System.out.println("ERROR******"+temp+name);
                        }

                    }
            }}
            temp=obj.pop();
        }
        obj.display();

//        for(int i=0;i<directory.length;i++)
//        System.out.println(directory[i]);
    }

    public GetList() {
        this.stack = new ArrayList<>();
        this.lnkFile=new ArrayList<>();
        this.progName=new ArrayList<>();
    }
    public void Push(String dir)
    {
        index++;
        //System.out.println("Push : "+dir+" "+index);
        this.stack.add(index,dir);

    }
    public String pop()
    {
        String dir="";
        if(index==-1)
            return "&%@#";
        else
        {
            dir=this.stack.get(index);
            //System.out.println("POP : "+dir+" "+index);
            index--;

        }
        return dir;
    }

    public void addFile(String name,String name2)
    {
        lnkFile.add(name);
        progName.add(name2);
    }

    public void display()
    {
        GetList.lnkFile.stream().forEach((lnkFile1) -> {
            System.out.println(lnkFile1);
        });
    }

}
0
Deepankar Sinha
public class searchingFile 
{
     static String path;//defining(not initializing) these variables outside main 
     static String filename;//so that recursive function can access them
     static int counter=0;//adding static so that can be accessed by static methods 

    public static void main(String[] args) //main methods begins
    {
        Scanner sc=new Scanner(System.in);
        System.out.println("Enter the path : ");
        path=sc.nextLine(); //storing path in path variable
        System.out.println("Enter file name : ");
        filename=sc.nextLine(); //storing filename in filename variable
        searchfile(path);//calling our recursive function and passing path as argument
        System.out.println("Number of locations file found at : "+counter);//Printing occurences

    }

    public static String searchfile(String path)//declaring recursive function having return 
                                                //type and argument both strings

    {
        File file=new File(path);//denoting the path
        File[] filelist=file.listFiles();//storing all the files and directories in array

    for (int i = 0; i < filelist.length; i++) //for loop for accessing all resources
    {
        if(filelist[i].getName().equals(filename))//if loop is true if resource name=filename
        {
            System.out.println("File is present at : "+filelist[i].getAbsolutePath());
            //if loop is true,this will print it's location
            counter++;//counter increments if file found
        }
        if(filelist[i].isDirectory())// if resource is a directory,we want to inside that folder
        {
            path=filelist[i].getAbsolutePath();//this is the path of the subfolder
            searchfile(path);//this path is again passed into the searchfile function 
                             //and this countinues untill we reach a file which has
                             //no sub directories

        }
    }
    return path;// returning path variable as it is the return type and also 
                // because function needs path as argument.

    }   
}
0
Shruti Mohan

En utilisant les fonctionnalités de Java 8+, nous pouvons écrire le code en quelques lignes:

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 renvoie un Stream<Path> qui "parcourt l’arborescence de fichiers enracinée à" la searchDirectory donnée. Pour sélectionner les fichiers souhaités, seul un filtre est appliqué à la variable Streamfiles. Il compare le nom de fichier d'une Path avec la fileName donnée.

Notez que la documentation de Files.walk nécessite

Cette méthode doit être utilisée dans une instruction try-with-resources ou structure de contrôle similaire pour garantir que les répertoires ouverts du flux sont fermés rapidement après la fin des opérations du flux.

J'utilise la déclaration try-resource-statement .


Pour les recherches avancées, une alternative consiste à utiliser une variable 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());

    }
}

Un exemple comment l'utiliser pour trouver un certain fichier:

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);
}

Pour en savoir plus: Didacticiel sur la recherche de fichiers Oracle

0
LuCio

Cette méthode effectuera une recherche récursive dans chaque répertoire en commençant à la racine, jusqu'à ce que le nom de fichier soit trouvé ou que tous les résultats restants soient renvoyés 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;
}
0
Kushroom