Java-Поиск файлов в каталоге

Это должно быть просто, но я не могу его получить - "напишите программу, которая ищет конкретное имя файла в данном каталоге."Я нашел несколько примеров жестко закодированного имени файла и каталога, но мне нужно, чтобы и dir, и имя файла были введены пользователем.

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

}

6 ответов


вы можете попробовать что-то вроде этого:

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

вот вывод:

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

Это похоже на вопрос домашней работы, поэтому я просто дам вам несколько советов:

попробуйте дать хорошие отличительные имена переменных. Здесь вы использовали "fileName" сначала для каталога, а затем для файла. Это сбивает с толку и не поможет вам решить проблему. Используйте разные названия для разных вещей.

вы не используете сканер ни для чего, и это не нужно здесь, избавиться от него.

кроме того, метод accept должен возвращать логическое значение. Прямо сейчас вы пытаетесь вернуть строку. Boolean означает, что он должен возвращать true или false. Например return a > 0; может возвращать true или false, в зависимости от значения a. Но!--1--> просто вернет значение fileName, которое является строкой.


Если вы хотите использовать динамический фильтр имени файла, вы можете реализовать FilenameFilter и передать в конструкторе динамическое имя.

конечно, это означает, что вы должны создавать экземпляр каждый раз, когда класс (накладные расходы), но он работает

пример:

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

}

затем вы используете, где вам нужно:

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

С * * Java 8 * есть альтернатива, которая использует потоки и лямбды:

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

Так это будет печатать все файлы рекурсивно:

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

и это будет искать файл:

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

я использовал другой подход для поиска файла с помощью стека.. имея в виду, что внутри папки могут быть папки. Хотя это не быстрее, чем поиск windows (и я не ожидал этого, хотя), но это определенно дает правильный результат. Пожалуйста, измените код, как вы хотите. Этот код был первоначально сделан для извлечения пути к файлу определенного расширения файла:). Не стесняйтесь оптимизировать.

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

}

следующий код помогает найти файл в каталоге и открыть его местоположение

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