Java将指定路径及其子路径下的文件移动到指定同一目录

709 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

背景:

很多时候,我们在迁移一些文件的时候,需要将不同文件夹下的文件,放到同一个文件夹下,进行处理。如此,便有了此文:

测试目录结构如下:

我这边是以视频为例,其余文件类似。 在这里插入图片描述

代码如下:

package com.wdy.ffmpeg.utils;

import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * 提取basePath文件夹下所有子文件到同一allPath文件夹下
 *
 * @author wangdy
 * @date 2021-03-30 11:45
 */
@Slf4j
public class ExtractDirFileUtil {
    private static final List<String> ALL_FILES = new ArrayList<>();
    private static final int BUFFER_SIZE = 16 * 1024;

    public static void main(String[] args) {
        String basePath = "G:\\2";
        String allPath = basePath + "\\all\\";
        copyBasePathFilesToAllPath(basePath, allPath);
    }

    /**
     * basePath 路径下的所有文件(包括子文件)都统一移动到allPath路径下
     *
     * @param basePath 原文件的根路径
     * @param allPath  新文件的根路径
     */
    public static void copyBasePathFilesToAllPath(String basePath, String allPath) {
        mkdir(allPath);
        File file = new File(basePath);
        if (!basePath.contains("\\all")) {
            if (file.isDirectory()) {
                //文件夹
                log.info("文件夹:" + file.getAbsolutePath());
                File[] listFiles = file.listFiles();
                for (int i = 0; i < Objects.requireNonNull(listFiles).length; i++) {
                    copyBasePathFilesToAllPath(listFiles[i].getAbsolutePath(), allPath);
                }
            } else {
                // 文件
                // 直接挪移到allPath文件夹中
                String fileName = file.getName().toLowerCase();
                if (isVideo(fileName)) {
                    if (excludeFiles(fileName)) {
                        //跳过
                        log.info("无效视频文件:" + fileName);
                    } else {
                        // 判端已经迁移的文件是否同名
                        if (ALL_FILES.contains(fileName)) {
                            String uuid = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 11);
                            String newFileName = uuid + fileName;
                            ALL_FILES.add(newFileName);
                            log.info("从" + file.getAbsolutePath() + "复制到 " + allPath + newFileName);
                            copyFile(file.getAbsolutePath(), allPath + newFileName);
                        } else {
                            ALL_FILES.add(fileName);
                            log.info("从" + file.getAbsolutePath() + "复制到 " + allPath + fileName);
                            copyFile(file.getAbsolutePath(), allPath + fileName);
                        }
                    }
                } else {
                    log.info("不是视频文件:" + fileName);
                }
            }
        }
    }

    /**
     * 简单判端是否为视频格式
     *
     * @param fileName 文件名
     * @return 是否为视频格式
     */
    private static boolean isVideo(String fileName) {
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
        List<String> extList = new ArrayList<>();
        extList.add("mp4");
        extList.add("avi");
        extList.add("flv");
        return extList.contains(ext.toLowerCase());
    }

    /**
     * 判端是否是不需要处理的文件
     *
     * @param fileName 文件名
     * @return 是否
     */
    private static boolean excludeFiles(String fileName) {
        // 各位可以提取出来放到容器中,统一判端,此处为示例
        return fileName.contains("不要的文件1.mp4") || fileName.contains("不要的文件2.mp4");
    }

    /* 【注意:】以下方法正常需要提取到FileUtil里,这里为各位更加直观*/

    /**
     * 用于创建文件夹的方法
     *
     * @param path 文件夹路径
     * @author wangdy
     */
    public static void mkdir(String path) {
        File file = new File(path);
        // 文件不存在
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    /**
     * 复制文件
     *
     * @param srcPath 源文件
     * @param dstPath 目标文件
     */
    public static void copyFile(String srcPath, String dstPath) {
        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            File src = new File(srcPath);
            File dst = new File(dstPath);
            in = new FileInputStream(src);
            out = new FileOutputStream(dst);
            byte[] buffer = new byte[BUFFER_SIZE];
            while (true) {
                int ins = in.read(buffer);
                if (ins == -1) {
                    in.close();
                    out.flush();
                    out.close();
                    break;
                } else {
                    out.write(buffer, 0, ins);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {//最后执行关闭资源操作
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.flush();
                    out.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}


运行日志如下:

为了给大家截2文件夹的层级关系,用idea开发工具打开了,所以输出了.idea的一些日志。

17:34:52.180 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 文件夹:G:\2
17:34:52.186 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 文件夹:G:\2\.idea
17:34:52.186 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 不是视频文件:.gitignore
17:34:52.186 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 不是视频文件:2.iml
17:34:52.186 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 不是视频文件:compiler.xml
17:34:52.186 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 不是视频文件:encodings.xml
17:34:52.186 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 文件夹:G:\2\.idea\inspectionProfiles
17:34:52.187 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 不是视频文件:project_default.xml
17:34:52.187 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 不是视频文件:misc.xml
17:34:52.187 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 不是视频文件:modules.xml
17:34:52.187 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 不是视频文件:workspace.xml
17:34:52.187 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 文件夹:G:\2\1-1
17:34:52.188 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 文件夹:G:\2\1-1\1-2
17:34:52.188 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 从G:\2\1-1\1-2\aaa.mp4复制到 G:\2\all\aaa.mp4
17:34:52.617 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 从G:\2\1-1\1-2\fff.mp4复制到 G:\2\all\fff.mp4
17:34:56.823 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 从G:\2\1-1\aaa.mp4复制到 G:\2\all\76c851f5f87aaa.mp4
17:34:57.191 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 从G:\2\aaa.mp4复制到 G:\2\all\48810ef3795aaa.mp4
17:34:57.762 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 从G:\2\fff.mp4复制到 G:\2\all\2d4f9042553fff.mp4
17:34:58.118 [main] INFO com.wdy.ffmpeg.utils.ExtractDirFileUtil - 从G:\2\副本.mp4复制到 G:\2\all\副本.mp4

结果截图:

在这里插入图片描述

综上:

1)重名的进行了重命名,大家也可以优化下,比如变为aaa(1).mp4 2) 非重名的进行了直接复制; 3)大家可以在复制后,进行删除源文件的操作。 警告:不自信的,可以复制,然后,手动删除,哈哈哈

在这里插入图片描述

END