Java 实现遍历一个文件夹,文件夹有100万数据,获取到修改时间在2天之内的数据

目录

  • [1 需求](#1 需求)
  • [2 实现1(第一种方法)](#2 实现1(第一种方法))
  • [2 实现2 (推荐使用这个,快)](#2 实现2 (推荐使用这个,快))
  • [3 实现3(推荐)](#3 实现3(推荐))

1 需求

现在有一个文件夹,里面会一直存数据,动态的存数据,之后可能会达到100万,1千万数据。

那么为了查询这个文件夹里面2天之内的数据,根据修改时间进行查询,我们如何操作

2 实现1(第一种方法)

java 复制代码
 /**
     * 遍历出一个文件夹下的全部的数据
     * */
    public static void getAllFile(File fileInput, List<File> allFileList) {
        // 获取文件列表
        File[] fileList = fileInput.listFiles();
        if (!ArrayUtil.isEmpty(fileList)) {
            for (File file : fileList) {
                if (file.isDirectory()) {
                    // 递归处理文件夹
                    // 如果不想统计子文件夹则可以将下一行注释掉
                    getAllFile(file, allFileList);
                } else {
                    // 如果是文件则将其加入到文件数组中
                    allFileList.add(file);
                }
            }
        }
    }
 /**
     * 一个文件夹


下前两天的全部的数据
     * */
    public static List<File> listOrderByDate(String fliePath) {
        // 存放的是一个文件夹下的全部的数据
        List<File> allFileList = new ArrayList<>();
        getAllFile(new File(fliePath), allFileList);
        long start = DateUtil.offsetDay(new Date(), -2).getTime();
        long end = new Date().getTime();
        List<File> collect = allFileList.parallelStream().filter(x -> x.lastModified() > start && x.lastModified() < end).collect(Collectors.toList());
        List<File> sortedCollect = collect.stream().sorted((t1, t2) -> Long.compare(t2.lastModified(), t1.lastModified())).collect(Collectors.toList());
        return sortedCollect;
    }
java 复制代码
 public static void main(String[] args) {

        long beginTime = System.currentTimeMillis();
        String psth = "D:\\100w\\dest";
        // 遍历文件夹
        List<File> files = listOrderByDate(psth);
        System.out.println(files.size());

        long endTime = System.currentTimeMillis();
        long l = endTime - beginTime;
        System.out.println(l/1000);


使用上面的方法,72608个文件,大小 都是50MB 左右的文件,花费了15秒

2 实现2 (推荐使用这个,快)

java 复制代码
 public static void main(String[] args) throws InterruptedException, ExecutionException {

        long beginTime = System.currentTimeMillis();
        String folderPath = "D:\\100w\\dest"; // 替换为实际的文件夹路径
        int numThreads = Runtime.getRuntime().availableProcessors(); // 获取可用的处理器核心数

        // 获取当前时间
        Date currentDate = new Date();

        // 计算两天前的时间
        long twoDaysAgoMillis = currentDate.getTime() - 2 * 24 * 60 * 60 * 1000;

        // 创建文件对象表示文件夹
        File folder = new File(folderPath);

        // 获取文件夹下的所有文件
        File[] files = folder.listFiles();

        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(numThreads);

        // 创建任务列表
        List<Callable<List<File>>> tasks = new ArrayList<>();

        // 将文件列表分成多个子列表
        int batchSize = 10000; // 每个子列表的大小
        if (files != null) {
            for (int i = 0; i < files.length; i += batchSize) {
                final int startIndex = i;
                final int endIndex = Math.min(i + batchSize, files.length);

                // 创建子任务,每个子任务处理一个子列表的文件
                Callable<List<File>> task = () -> {
                    List<File> result = new ArrayList<>();
                    for (int j = startIndex; j < endIndex; j++) {
                        File file = files[j];
                        // 检查文件最后修改时间是否在两天内
                        if (file.lastModified() >= twoDaysAgoMillis) {
                            result.add(file);
                        }
                    }
                    return result;
                };

                tasks.add(task);
            }
        }

        // 提交并行任务
        List<Future<List<File>>> futures = executor.invokeAll(tasks);

        // 收集结果
        List<File> result = new ArrayList<>();
        for (Future<List<File>> future : futures) {
            result.addAll(future.get());
        }

        // 关闭线程池
        executor.shutdown();

        // 处理结果,例如打印文件名
        System.out.println(result.size());

        long endTime = System.currentTimeMillis();
        long l = endTime - beginTime;
        System.out.println(l/1000);

获取是1秒

3 实现3(推荐)

java 复制代码
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        String folderPath = "D:\\100w\\dest"; // 替换为实际的文件夹路径
        List<File> modifiedFiles = getModifiedFilesWithinTwoDays(folderPath);
        System.out.println("修改时间在2天之内的文件数量: " + modifiedFiles.size());
        long end = System.currentTimeMillis();
        long ss =  end - start;
        System.out.println(ss/1000);
        // 处理修改时间在2天之内的文件数据
    }

    public static List<File> getModifiedFilesWithinTwoDays(String folderPath) {
        List<File> modifiedFiles = new ArrayList<>();
        File folder = new File(folderPath);

        if (folder.exists() && folder.isDirectory()) {
            File[] files = folder.listFiles();
            if (files != null) {
                Instant twoDaysAgo = Instant.now().minus(Duration.ofDays(2));

                for (File file : files) {
                    try {
                        BasicFileAttributes attrs = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
                        Instant lastModifiedTime = attrs.lastModifiedTime().toInstant();
                        if (lastModifiedTime.isAfter(twoDaysAgo)) {
                            modifiedFiles.add(file);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        return modifiedFiles;
    }
相关推荐
weixin_462428474 分钟前
使用 Caffeine 缓存并在业务方法上通过注解实现每3到5秒更新缓存
java·缓存
程序媛小果6 分钟前
基于java+SpringBoot+Vue的桂林旅游景点导游平台设计与实现
java·vue.js·spring boot
骑鱼过海的猫1237 分钟前
【java】java通过s3访问ceph报错
java·ceph·iphone
杨充13 分钟前
13.观察者模式设计思想
java·redis·观察者模式
Lizhihao_16 分钟前
JAVA-队列
java·开发语言
denghai邓海16 分钟前
红黑树删除之向上调整
python·b+树
喵叔哟25 分钟前
重构代码之移动字段
java·数据库·重构
喵叔哟25 分钟前
重构代码之取消临时字段
java·前端·重构
fa_lsyk27 分钟前
maven环境搭建
java·maven
远望清一色34 分钟前
基于MATLAB边缘检测博文
开发语言·算法·matlab