13

这应该很简单,但我无法理解——“编写一个在给定目录中搜​​索特定文件名的程序。” 我找到了一些硬编码文件名和目录的示例,但我需要用户输入的目录和文件名。

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

}
4

10 回答 10

32

你可以尝试这样的事情:

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
于 2013-03-25T20:45:49.950 回答
9

使用 Java 8+ 的特性,我们可以用几行代码编写代码:

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返回一个Stream<Path>“遍历文件树根”给定的searchDirectory. 要选择所需的文件,只需在Stream files. 它将 a 的文件名Path与给定的fileName.

请注意,要求的文档Files.walk

此方法必须在 try-with-resources 语句或类似的控制结构中使用,以确保在流的操作完成后立即关闭流的打开目录。

我正在使用try-resource-statement


对于高级搜索,另一种方法是使用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());

    }
}

如何使用它来查找某个文件的示例:

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

有关它的更多信息:Oracle 查找文件教程

于 2018-12-04T09:05:00.497 回答
3

使用 **Java 8* 有一个使用流和 lambda 的替代方案:

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);
  }
});
于 2017-04-06T09:11:26.157 回答
1

如果要使用动态文件名过滤器,可以实现 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);
于 2014-08-06T20:41:59.737 回答
1

这看起来像一个家庭作业问题,所以我会给你一些建议:

尝试给出良好的独特变量名称。在这里,您首先将“fileName”用于目录,然后用于文件。这很令人困惑,并且不会帮助您解决问题。对不同的事物使用不同的名称。

您没有将 Scanner 用于任何事情,并且这里不需要它,请摆脱它。

此外,accept 方法应该返回一个布尔值。现在,您正试图返回一个字符串。布尔值意味着它应该返回 true 或 false。例如return a > 0;可能返回真或假,取决于 a 的值。但return fileName;只会返回文件名的值,它是一个字符串。

于 2013-03-25T20:39:26.677 回答
0

我使用了另一种方法来使用堆栈搜索文件。请记住,文件夹内可能有文件夹。虽然它并不比 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);
        });
    }

}
于 2015-02-15T18:29:46.143 回答
0
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.

    }   
}
于 2019-01-05T16:13:33.000 回答
0

此方法将从根目录开始递归搜索每个目录,直到找到 fileName,或者所有剩余结果都返回 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;
}
于 2018-11-29T03:21:14.053 回答
0

以下代码有助于在目录中搜索文件并打开其位置

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);                               
            }                      
        }        
      }
    }        
}
于 2016-12-20T07:52:25.763 回答
-1

我尝试了很多方法来找到我想要的文件类型,这是我完成后的结果。

public static void main( String args[]){
final String dir2 = System.getProperty("user.name"); \\get user name 
String path = "C:\\Users\\" + dir2; 
digFile(new File(path)); \\ path is file start to dig
    
   for (int i = 0; i < StringFile.size(); i++) {
         
   System.out.println(StringFile.get(i));
        
    }
 }

private void digFile(File dir) {

    FilenameFilter filter = new FilenameFilter() {
        public boolean accept(File dir, String name) {
            return name.endsWith(".mp4");
        }
    };      
    String[] children = dir.list(filter);

   
    if (children == null) {
        return;
    } else {
        for (int i = 0; i < children.length; i++) {
            StringFile.add(dir+"\\"+children[i]);

        }
    }

    File[] directories;
    directories = dir.listFiles(new FileFilter() {
        @Override
        public boolean accept(File file) {
            return file.isDirectory();
        }
    
        public boolean accept(File dir, String name) {
            return !name.endsWith(".mp4");
        }
    });
        
   if(directories!=null)
   {
       for (File directory : directories) {
           digFile(directory);
       }
   }
    
}
于 2021-01-22T11:54:02.433 回答