【问题标题】:Find files in a folder using Java使用 Java 在文件夹中查找文件
【发布时间】:2011-06-18 15:51:56
【问题描述】:

如果搜索文件夹说C:\example我需要做什么

然后我需要检查每个文件并检查它是否与几个开始字符匹配,以便文件开始

temp****.txt
tempONE.txt
tempTWO.txt

因此,如果文件以 temp 开头并具有扩展名 .txt 我想将该文件名放入 File file = new File("C:/example/temp***.txt); 以便我可以读取文件,然后循环需要移动到下一个文件检查是否符合上述要求。

【问题讨论】:

    标签: java file search for-loop directory


    【解决方案1】:

    从 Java 8 开始,您可以使用 Files.find

    Path dir = Paths.get("path/to/search");
    String prefix = "prefix";
    
    Files.find(dir, 3, (path, attributes) -> path.getFileName().toString().startsWith(prefix))
                    .forEach(path -> log.info("Path = " + path.toString()));
    

    【讨论】:

      【解决方案2】:

      正如@Clarke 所说,您可以使用java.io.FilenameFilter 按特定条件过滤文件。

      作为补充,我想展示如何使用java.io.FilenameFilter 来搜索当前目录及其子目录中的文件。

      常用方法getTargetFiles和printFiles用于搜索文件并打印。

      public class SearchFiles {
      
          //It's used in dfs
          private Map<String, Boolean> map = new HashMap<String, Boolean>();
      
          private File root;
      
          public SearchFiles(File root){
              this.root = root;
          }
      
          /**
           * List eligible files on current path
           * @param directory
           *      The directory to be searched
           * @return
           *      Eligible files
           */
          private String[] getTargetFiles(File directory){
              if(directory == null){
                  return null;
              }
      
              String[] files = directory.list(new FilenameFilter(){
      
                  @Override
                  public boolean accept(File dir, String name) {
                      // TODO Auto-generated method stub
                      return name.startsWith("Temp") && name.endsWith(".txt");
                  }
      
              });
      
              return files;
          }
      
          /**
           * Print all eligible files
           */
          private void printFiles(String[] targets){
              for(String target: targets){
                  System.out.println(target);
              }
          }
      }
      

      我将演示如何使用 recursivebfsdfs 来完成工作。

      递归

          /**
       * How many files in the parent directory and its subdirectory <br>
       * depends on how many files in each subdirectory and their subdirectory
       */
      private void recursive(File path){
      
          printFiles(getTargetFiles(path));
          for(File file: path.listFiles()){
              if(file.isDirectory()){
                  recursive(file);
              }
          }
          if(path.isDirectory()){
              printFiles(getTargetFiles(path));
          }
      }
      
      public static void main(String args[]){
          SearchFiles searcher = new SearchFiles(new File("C:\\example"));
          searcher.recursive(searcher.root);
      }
      

      广度优先搜索

      /**
       * Search the node's neighbors firstly before moving to the next level neighbors
       */
      private void bfs(){
          if(root == null){
              return;
          }
      
          Queue<File> queue = new LinkedList<File>();
          queue.add(root);
      
          while(!queue.isEmpty()){
              File node = queue.remove();
              printFiles(getTargetFiles(node));
              File[] childs = node.listFiles(new FileFilter(){
      
                  @Override
                  public boolean accept(File pathname) {
                      // TODO Auto-generated method stub
                      if(pathname.isDirectory())
                          return true;
      
                      return false;
                  }
      
              });
      
              if(childs != null){
                  for(File child: childs){
                      queue.add(child);
                  }
              }
          }
      }
      
      public static void main(String args[]){
          SearchFiles searcher = new SearchFiles(new File("C:\\example"));
          searcher.bfs();
      }
      

      深度优先搜索

       /**
       * Search as far as possible along each branch before backtracking
       */
      private void dfs(){
      
          if(root == null){
              return;
          }
      
          Stack<File> stack = new Stack<File>();
          stack.push(root);
          map.put(root.getAbsolutePath(), true);
          while(!stack.isEmpty()){
              File node = stack.peek();
              File child = getUnvisitedChild(node);
      
              if(child != null){
                  stack.push(child);
                  printFiles(getTargetFiles(child));
                  map.put(child.getAbsolutePath(), true);
              }else{
                  stack.pop();
              }
      
          }
      }
      
      /**
       * Get unvisited node of the node
       * 
       */
      private File getUnvisitedChild(File node){
      
          File[] childs = node.listFiles(new FileFilter(){
      
              @Override
              public boolean accept(File pathname) {
                  // TODO Auto-generated method stub
                  if(pathname.isDirectory())
                      return true;
      
                  return false;
              }
      
          });
      
          if(childs == null){
              return null;
          }
      
          for(File child: childs){
      
              if(map.containsKey(child.getAbsolutePath()) == false){
                  map.put(child.getAbsolutePath(), false);
              }
      
              if(map.get(child.getAbsolutePath()) == false){
                  return child; 
              }
          }
      
          return null;
      }
      
      public static void main(String args[]){
          SearchFiles searcher = new SearchFiles(new File("C:\\example"));
          searcher.dfs();
      }
      

      【讨论】:

        【解决方案3】:
        • Matcher.find 和 Files.walk 方法可能是一种以更灵活的方式搜索文件的选项
        • String.format 结合正则表达式来创建搜索限制
        • Files.isRegularFile 检查路径是否不是目录、符号链接等。

        用法:

        //Searches file names (start with "temp" and extension ".txt")
        //in the current directory and subdirectories recursively
        Path initialPath = Paths.get(".");
        PathUtils.searchRegularFilesStartsWith(initialPath, "temp", ".txt").
                                               stream().forEach(System.out::println);
        

        来源:

        public final class PathUtils {
        
            private static final String startsWithRegex = "(?<![_ \\-\\p{L}\\d\\[\\]\\(\\) ])";
            private static final String endsWithRegex = "(?=[\\.\\n])";
            private static final String containsRegex = "%s(?:[^\\/\\\\]*(?=((?i)%s(?!.))))";
        
            public static List<Path> searchRegularFilesStartsWith(final Path initialPath, 
                                     final String fileName, final String fileExt) throws IOException {
                return searchRegularFiles(initialPath, startsWithRegex + fileName, fileExt);
            }
        
            public static List<Path> searchRegularFilesEndsWith(final Path initialPath, 
                                     final String fileName, final String fileExt) throws IOException {
                return searchRegularFiles(initialPath, fileName + endsWithRegex, fileExt);
            }
        
            public static List<Path> searchRegularFilesAll(final Path initialPath) throws IOException {
                return searchRegularFiles(initialPath, "", "");
            }
        
            public static List<Path> searchRegularFiles(final Path initialPath,
                                     final String fileName, final String fileExt)
                    throws IOException {
                final String regex = String.format(containsRegex, fileName, fileExt);
                final Pattern pattern = Pattern.compile(regex);
                try (Stream<Path> walk = Files.walk(initialPath.toRealPath())) {
                    return walk.filter(path -> Files.isRegularFile(path) &&
                                               pattern.matcher(path.toString()).find())
                            .collect(Collectors.toList());
                }
            }
        
            private PathUtils() {
            }
        }
        

        Try startsWith \txt\temp\tempZERO0.txt 的正则表达式:

        (?<![_ \-\p{L}\d\[\]\(\) ])temp(?:[^\/\\]*(?=((?i)\.txt(?!.))))
        

        Try endsWith \txt\temp\ZERO0temp.txt 的正则表达式:

        temp(?=[\\.\\n])(?:[^\/\\]*(?=((?i)\.txt(?!.))))
        

        Try 包含 \txt\temp\tempZERO0tempZERO0temp.txt 的正则表达式:

        temp(?:[^\/\\]*(?=((?i)\.txt(?!.))))
        

        【讨论】:

          【解决方案4】:

          从 Java 1.8 开始,您可以使用 Files.list 来获取流:

          Path findFile(Path targetDir, String fileName) throws IOException {
              return Files.list(targetDir).filter( (p) -> {
                  if (Files.isRegularFile(p)) {
                      return p.getFileName().toString().equals(fileName);
                  } else {
                      return false;
                  }
              }).findFirst().orElse(null);
          }
          

          【讨论】:

            【解决方案5】:

            您提供文件的名称、要搜索的目录路径,然后让它完成工作。

            private static String getPath(String drl, String whereIAm) {
                File dir = new File(whereIAm); //StaticMethods.currentPath() + "\\src\\main\\resources\\" + 
                for(File e : dir.listFiles()) {
                    if(e.isFile() && e.getName().equals(drl)) {return e.getPath();}
                    if(e.isDirectory()) {
                        String idiot = getPath(drl, e.getPath());
                        if(idiot != null) {return idiot;}
                    }
                }
                return null;
            }
            

            【讨论】:

              【解决方案6】:

              详细说明this response,Apache IO Utils 可能会为您节省一些时间。考虑以下示例,它将递归搜索给定名称的文件:

                  File file = FileUtils.listFiles(new File("the/desired/root/path"), 
                              new NameFileFilter("filename.ext"), 
                              FileFilterUtils.trueFileFilter()
                          ).iterator().next();
              

              见:

              【讨论】:

                【解决方案7】:

                考虑一下 Apache Commons IO,它有一个名为 FileUtils 的类,它有一个 listFiles 方法,在您的情况下可能非常有用。

                【讨论】:

                  【解决方案8】:

                  我知道,这是一个老问题。但只是为了完整起见,lambda 版本。

                  File dir = new File(directory);
                  File[] files = dir.listFiles((dir1, name) -> name.startsWith("temp") && name.endsWith(".txt"));
                  

                  【讨论】:

                  • 这是更性感的解决方案
                  【解决方案9】:

                  Appache commons IO 各种

                  FilenameUtils.wildcardMatch

                  请参阅 Apache javadoc here。它将通配符与文件名匹配。因此,您可以使用此方法进行比较。

                  【讨论】:

                  • 如此简洁的答案很容易被标记为低质量。
                  • 我的声誉不允许我添加评论。我可以贡献的唯一方法是添加另一个答案。我编辑了原始帖子以添加更多详细信息。
                  【解决方案10】:

                  列出给定目录中的 Json 文件。

                  import java.io.File;
                      import java.io.FilenameFilter;
                  
                      public class ListOutFilesInDir {
                          public static void main(String[] args) throws Exception {
                  
                              File[] fileList = getFileList("directory path");
                  
                              for(File file : fileList) {
                                  System.out.println(file.getName());
                              }
                          }
                  
                          private static File[] getFileList(String dirPath) {
                              File dir = new File(dirPath);   
                  
                              File[] fileList = dir.listFiles(new FilenameFilter() {
                                  public boolean accept(File dir, String name) {
                                      return name.endsWith(".json");
                                  }
                              });
                              return fileList;
                          }
                      }
                  

                  【讨论】:

                    【解决方案11】:

                    看看java.io.File.list()FilenameFilter

                    【讨论】:

                      【解决方案12】:

                      您可以使用FilenameFilter,如下所示:

                      File dir = new File(directory);
                      
                      File[] matches = dir.listFiles(new FilenameFilter()
                      {
                        public boolean accept(File dir, String name)
                        {
                           return name.startsWith("temp") && name.endsWith(".txt");
                        }
                      });
                      

                      【讨论】:

                      • +1 因为变量名称比你之前 2 分钟发布的几乎相同的代码更令人愉悦。
                      • @Null Set,这个答案是在我写我的时候写的,所以这不像我复制了贾斯汀写的东西并重新命名了变量...... :) 谢谢你的投票.
                      • +1 和我的想法一模一样。
                      • @Justin 'jjnguy' Nelson 回到你身边!
                      • +1 因为你的变量被命名得更好,而且你的 endwith 有扩展点
                      【解决方案13】:

                      你想要的是File.listFiles(FileNameFilter filter)

                      这将为您提供目录中与特定过滤器匹配的文件列表。

                      代码将类似于:

                      // your directory
                      File f = new File("C:\\example");
                      File[] matchingFiles = f.listFiles(new FilenameFilter() {
                          public boolean accept(File dir, String name) {
                              return name.startsWith("temp") && name.endsWith("txt");
                          }
                      });
                      

                      【讨论】:

                      • BTW Java 在 Windows 下可以很好地处理斜线 (/)。所以不需要反斜杠(并转义它)。
                      • 如果你在 Java 7 下,你可以/应该使用 java.nio.FileSystems.getDefault().getPath(String dir1, String dir2, ...) 在一个真正的“多平台方式”
                      • @beder 是java.nio.file.FileSystems
                      猜你喜欢
                      • 2015-10-03
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2020-11-05
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多