【问题标题】:Java - Search for files in a directoryJava - 在目录中搜索文件
【发布时间】:2013-03-25 20:34:21
【问题描述】:

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

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

}

【问题讨论】:

标签: java file search directory


【解决方案1】:

你可以试试这样的:

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

【讨论】:

  • 嗨@Vishal,这段代码不能帮助我从用户那里获取目录和文件名,这是问题所在。
  • 这段代码给了你文件所在目录的完整路径。运行这段代码..在main方法中更改find​​File的参数。
  • 谢谢,我想自己解决,但你的比我的好!非常感谢。
  • 非常感谢。更清晰
【解决方案2】:

使用 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&lt;Path&gt;,它正在“遍历以给定searchDirectory 为根的文件树”。要选择所需的文件,只需在Stream files 上应用过滤器。它将Path 的文件名与给定的fileName 进行比较。

注意Files.walkdocumentation 需要

此方法必须在 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 Finding Files tutorial

【讨论】:

    【解决方案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);
      }
    });
    

    【讨论】:

    • 这对我来说太复杂了
    • 使用peek() 不是为了调试,而且还有一个副作用是"strongly discouraged"
    【解决方案4】:

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

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

    你没有使用 Scanner 做任何事情,这里也不需要它,摆脱它。

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

    【讨论】:

      【解决方案5】:

      如果您想使用动态文件名过滤器,您可以实现 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);
      

      【讨论】:

      • 你确定file = new File(name):这将从一个简单的名称构建一个文件,它不属于walked目录。所以做file.isDirectory() 可能会给你意想不到的结果。我会选择new File(name, dir)
      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

          【解决方案8】:

          此方法将从根目录开始递归搜索每个目录,直到找到文件名,或者所有剩余结果都返回空。

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

          【讨论】:

            【解决方案9】:
            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.
            
                }   
            }
            

            【讨论】:

            • 在代码上方添加最少的文字,以描述在有人跳入代码之前它会做什么。
            【解决方案10】:

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

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

            【讨论】:

            • 请在本网站的英文版上使用英文。如果您用英文翻译更新您的答案,它可能不会被删除
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-09-09
            • 1970-01-01
            • 2018-04-26
            • 2015-06-07
            • 1970-01-01
            • 2016-02-29
            • 2010-09-05
            相关资源
            最近更新 更多