代码之家  ›  专栏  ›  技术社区  ›  KayV

使用Java8在目录和子目录中查找文件

  •  6
  • KayV  · 技术社区  · 8 年前

    如何在中实现算法 Java 8 ,给定开始目录和文件名,它搜索给定目录中的文件或嵌套不超过5级的任何子目录。

    例如,考虑以下目录结构:

    Folder 1
       Folder 2
          Folder 3
            Folder 4
                Folder 5
                    Folder 6
                        nfiles.txt....
                    MyFile.txt
                    xfile.txt
                filesInFolder4....
            filesInFolder3...
       .....
    

    算法应搜索文件夹5中包含的文件,并报告是否存在具有给定文件名的文件?

    如何使用 Java 8 ?

    4 回复  |  直到 7 年前
        1
  •  14
  •   Anton Balaniuc    8 年前

    请看一下 Files.find 方法

    try (Stream<Path> stream = Files.find(Paths.get("Folder 1"), 5,
                (path, attr) -> path.getFileName().toString().equals("Myfile.txt") )) {
            System.out.println(stream.findAny().isPresent());
    } catch (IOException e) {
            e.printStackTrace();
    }
    
        2
  •  1
  •   KayV    8 年前

    我找到了处理文件的解决方案。查找和文件。按如下方式行走:

    // Finding a file upto x level in File Directory using NIO Files.find
        Path start = Paths.get("/Users/***/Documents/server_pull");
        int maxDepth = 5;
        try(Stream<Path> stream = Files.find(start, 
                                            maxDepth, 
                                            (path, attr) -> String.valueOf(path).endsWith(".json"))){
            String fileName = stream
                                .sorted()
                                .map(String::valueOf)
                                .filter((path) -> {
                                    //System.out.println("In Filter : "+path);
                                    return String.valueOf(path).endsWith("system_health_12_55_TestServer.json");
                                })
                                .collect(Collectors.joining());
            System.out.println("fileName : "+fileName);
        }catch(Exception e){
            e.printStackTrace();
        }
    
    // Finding a file upto x level in File Directory using NIO Files.walk
    
        Path startWalk = Paths.get("/Users/***/Documents/server_pull");
        int depth = 5;
        try( Stream<Path> stream1 = Files.walk(startWalk, 
                                                depth)){
            String walkedFile = stream1
                                .map(String::valueOf)
                                .filter(path -> {
                                    return String.valueOf(path).endsWith("system_health_12_55_TestServer.json");
                                })
                                .sorted()
                                .collect(Collectors.joining());
            System.out.println("walkedFile = "+walkedFile);
    
        }catch(Exception e){
            e.printStackTrace();
        }
    

    它似乎比walkFileTree更简单。。。

        3
  •  1
  •   user3656845    3 年前
    public static String getAdobeExePath(String basePath, String exeName) {
        File[] files = new File(basePath).listFiles();
        String foundPath;
        for (int i = 0; i < files.length; i++) {
            if (files[i].isDirectory()) {
                foundPath = getAdobeExePath(files[i].getAbsolutePath(), exeName);
                if (foundPath != null) {
                    return foundPath;
                }
            }else {
                if (exeName.equals(files[i].getName())) {
                    return files[i].getAbsolutePath();
                }
            }
        }
        return null;
    }
    

    这是使用递归。

        4
  •  0
  •   KayV    6 年前

    我对这个问题做了进一步的深入研究,并找到了一种使用ForkJoinPool以同步方式完成这项工作的方法,如下所示:

    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ForkJoinPool;
    import java.util.concurrent.RecursiveTask;
    import java.util.concurrent.TimeUnit;
    
    
    
    public class ForkJoinFolderProcessor {
    
        public static void main(String[] args) {
            ForkJoinPool pool = new ForkJoinPool();
    
    
            MyFolderProcessor hadoop = new MyFolderProcessor("/Users/*****/backups/h/", "log");
            MyFolderProcessor t8 = new MyFolderProcessor("/Users/*******/apache-tomcat-9.0.2", "log");
            MyFolderProcessor t9 = new MyFolderProcessor("/Users/******/apache-tomcat-8.5.20", "log");
    
            pool.execute(hadoop);
            pool.execute(t8);
            pool.execute(t9);
    
            do {
                System.out.println("---------------------");
                System.out.println("Parallelism : "+pool.getParallelism());
                System.out.println("Active Threads : "+pool.getActiveThreadCount());
                System.out.println("Task Count : "+pool.getQueuedTaskCount());
                System.out.println("Steal Count : "+pool.getStealCount());
    
                System.out.println("---------------------");
    
                try
                 {
                    TimeUnit.SECONDS.sleep(1);
                 } catch (InterruptedException e)
                 {
                    e.printStackTrace();
                 }
            }while((!hadoop.isDone()) || (!t8.isDone()) || (!t9.isDone()));
    
            pool.shutdown();
    
            List<String> results = hadoop.join();
            System.out.println("Hadoop: Files found  : " + results.size()+" "+results.toString());
            results = t8.join();
            System.out.println("T8: Files found  : " + results.size()+" "+results.toString());
            results = t9.join();
            System.out.println("T9: Files found  : " + results.size()+" "+results.toString());
    
        }
    
    }
    
    class MyFolderProcessor extends RecursiveTask<List<String>>{
    
        private static final long serialVersionUID = 1L;
    
        private final String filepath;
        private final String fileExt;
    
        public MyFolderProcessor(String path, String extension) {
            this.filepath = path;
            this.fileExt = extension;
        }
    
        @Override
        protected List<String> compute() {
    
            List<String> list = new ArrayList<String>();
            List<MyFolderProcessor> tasks = new ArrayList<MyFolderProcessor>();
    
            File file = new File(filepath);
            File content[] = file.listFiles();
    
            if(content != null) {
                    for(File f : content) {
                        if(f.isDirectory()) {
                            MyFolderProcessor task = new MyFolderProcessor(f.getAbsolutePath(), fileExt);
                            task.fork();
                            tasks.add(task);
                        }else {
                            if(checkFile(f.getName()))
                                list.add(f.getAbsolutePath());
                        }
                    }
            }
            if (tasks.size() > 50) {
                System.out.println("tasks ran."+ file.getAbsolutePath()+" "+ tasks.size());
            }
            addResultsFromTasks(list, tasks);
    
            return list;
        }
    
        private void addResultsFromTasks(List<String> list, List<MyFolderProcessor> tasks) {
            for (MyFolderProcessor item : tasks) {
                list.addAll(item.join());
            }
        }
    
        private boolean checkFile(String name) {
            return name.endsWith(fileExt);
        }
    
    }
    

    虽然这是一个更复杂的解决方案,但它在多线程环境中工作得非常好。