java递归遍历文件夹寻找指定文件以及其代码优化

1.问题描述

        递归遍历某个路径下的所有文件,找到以某个指定或某类文件,输出其路径,以遍历F盘查找java文件(.java结尾)为例,进行讨论

2.普通实现

        最简单的实现就是直接使用递归遍历指定路径

2.1普通实现代码

import java.io.File;

public class AlgorithmFile{
    public static void main(String[] args) {
        searchFile(new File("F:"));
    }

    /**
     * 
     * @Description 递归遍历指定路径下的所有文件,并找到以.java结尾的文件
     * @param file File对象,提供一个路径
     */
    private static void searchFile(File file) {
        /**
         * 判断是否为文件夹
         *          如果是递归遍历
         *          如果不是判断是否为.java结尾
         *                  如果是则输出其绝对路径
         */
       if(file.isDirectory()) {
           File[] listFiles = file.listFiles();//获取路径下的所有文件(包括文件夹与文件)
           if(listFiles != null && listFiles.length > 0) {
               for(File f:listFiles) {
                   searchFile(f);
               }
           }
       }else{
          if(file.getName().endsWith(".java")) {
              System.out.println(file);
          }
       }
    }
}

2.2运行结果

在这里插入图片描述运行是没有问题的,只是比较慢。

2.3 实现讨论

        这样实现确实没有问题,但是如果指定路径下(F盘)的内容很多,就会花费很长时间,要考虑如何提升速度,肯定是多线程,那就用多线程来实现初步的优化。

3.多线程实现

3.1 思路

        使用多线程,将不同的子路径交给不同的线程去递归,这样就会达到“多路并进”的效果,大大减少所需的时间,提高效率,但是线程也并非是越多越好,而实际上,在能满足性能需求的前提下,线程是越少越好的,这样可以极大地减少系统资源的开销,而且windows系统中运行的总线程数最好不要超过cpu数目 * 2 + 2 (可以参开Windows多线程编程的相关资料),那么在这里使用线程池来创建指定数目的线程,复用这些线程达到提高效率的作用

3.2代码实现

import java.io.File;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

public class AlgorithmFile {

    private static ScheduledExecutorService newScheduledThreadPool;

    public static void main(String[] args) {
        newScheduledThreadPool = Executors.newScheduledThreadPool(10);
        newScheduledThreadPool.submit(new MyThread(new File("F:")));
    }
    
    private static class MyThread implements Runnable {

        private File file;

        public MyThread(File file) {
            this.file = file;
        }

        @Override
        public void run() {
           File[] listFiles = file.listFiles();
            if (listFiles != null && listFiles.length > 0) {
                for (File f : listFiles) {
                    if (f.isDirectory()) {
                        newScheduledThreadPool.submit(new MyThread(f));
                    } else {
                        if(f.getName().endsWith(".java")){
                            System.out.println(new Thread().currentThread().getName() + " : " + file);
                        }
                    }
                }
            }
        }

    }
}

3.3运行结果

在这里插入图片描述运行速度会比之前快很多,但是代码就会很复杂,使用Lambda表达式与可变参数来进行代码结构的优化

4.使用Lambda表达式与可变参数优化代码结构

4.1基本思路

        使用Lambda表达式简化代码结构主要是省略继承Thread或实现Runnable的过程,利用Lambda直接将在run方法中执行的代码提炼出来放在lambda表达式的代码块中,实现多线程

4.2代码实现

import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AlgorithmFile {
    private static ExecutorService newFixedThreadPool;

    public static void main(String[] args) {
        File file = new File("F:");
        newFixedThreadPool = Executors.newFixedThreadPool(10);
        searchFile(file);
    }
    
    public static void searchFile(File ... file) {
        if(file != null && file.length > 0) {
            for(File f : file) {
                newFixedThreadPool.submit(() -> {
                    if(f.isDirectory()) {
                        searchFile(f.listFiles());
                    }else{
                        if(f.getName().endsWith(".java")) {
                            System.out.println(new Thread().currentThread().getName() + " --- >  " + f);
                        }
                    }
                 });
            }
        }
    }
}

4.3运行结果

在这里插入图片描述达到同样的优化目标。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页