用Java程序来判断两个文件夹中的重复文件并删除

用Java程序来判断两个文件夹中的重复文件并删除

今天把旧电脑的硬盘里面的音乐文件拷贝到新机器中,发现很多歌曲是重复的,但是又不是统一放置于一个文件夹最外层,而是有的按照歌手名称分类,有的是放外层,无法直接拷贝覆盖,又心疼存储,所以就想写一个程序来把我进行去重吧!!!

1.文件去重

package cn.zju.ZhXiQi;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class TestOne {
    public static void main(String[] args) throws IOException, InterruptedException {
				//可以设置为args[0]、args[1] 从外部接收参数
        String pathOne = "/Users/ZhXiQi/OneDrive - zju.edu.cn/CloudMusic";
        String pathTwo = "/Users/ZhXiQi/Music";

        File fileOne = new File(pathOne);
        int fileNums = getFileNums(pathOne);
        List<File> fileList = new ArrayList<>(fileNums+10);
        File[] listFilesOne = fileOne.listFiles();
        Stream.of(listFilesOne).forEach(file -> {
            findFile(file,fileList);
        });

        File fileTwo = new File(pathTwo);
        File[] filesTwo = fileTwo.listFiles();
        int fileNumsTwo = getFileNums(pathTwo);
        List<File> targetFileList = new ArrayList<>(fileNumsTwo+10);
        Stream.of(filesTwo).parallel().forEach(file -> {
            findFile(file,targetFileList);
        });

        deleteDuplicate(targetFileList,fileList);
    }

    /**
     * 递归找文件,因为找的时候是开并行流找,找到文件添加到一个列表中,所以需要预先设置足够大的列表,否则会列表来不及扩容导致数组越界问题
     * @param file
     * @param fileList
     */
    public static void findFile(File file,List<File> fileList){
        if (file.isDirectory()){
            File[] files = file.listFiles();
            Stream.of(files).parallel().forEach(f -> {
                findFile(f,fileList);
            });
        }else {
            fileList.add(file);
        }
    }

    /**
     * 利用shell指令来计算指定文件夹下的文件数
     * @param path 指定目录
     * @return
     * @throws InterruptedException
     * @throws IOException
     */
    public static int getFileNums(String path) throws InterruptedException, IOException {
        String replace = path.replace(" ", "\\ ");
      	//Java具有使用Runtime.exec对本地程序调用进行重定向的能力,但是用重定向或者管道进行命令调用将会出错。解决这一问题的办法是通过命令shell运行命令
        String[] cmd = { "/bin/sh", "-c", "ls -lR "+replace+" | grep ^- | wc -l" };
        Process exec = Runtime.getRuntime().exec(cmd);
        exec.waitFor();
        //获取 shell 指令执行结果
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(exec.getInputStream(), "UTF-8"));
        //shell指令执行错误流
//        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(exec.getErrorStream(), "UTF-8"));
        StringBuilder result = new StringBuilder();
        String line;
        while ((line = bufferedReader.readLine())!=null){
            result.append(line);
        }
        return Integer.parseInt(result.toString().trim());
    }

    /**
     * 删除重复文件
     * @param origin
     * @param target
     */
    public static void deleteDuplicate(List<File> origin, List<File> target){
        target.parallelStream().forEach(file -> {
            origin.parallelStream().forEach(f -> {
                if (f != null){
                    //只是单纯的按照文件名来删除,如果有需要可以使用 文件hash等来确定是否同一份文件
                    if (f.getName().equals(file.getName())){
                        System.out.println(f.getAbsolutePath());
                        f.deleteOnExit();
                    }
                }
            });

        });
    }
}

程序比较简单,纯娱乐向。

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦