删除目录下的重复文件,优先删除"副本"

来源:互联网 发布:苹果千牛mac工作台 编辑:程序博客网 时间:2024/05/18 00:08

        一直以来收藏的经典歌曲已经有好几百首,而且不同时期喜欢听不同的,在主文件夹下有些重复的.mp3文件,很占内存,手机上1.5G都是歌曲文件,近来用程序实现删除重复文件,且优先删除文件名包含“副本”的。相同文件(文件属性、文件名等)只留一份。

package com.ljheee.file;import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;public class DelExistedFiles {// 定义一个List,用来存放不重复的文件的MD5值private List<String> md5List = new ArrayList<String>();// <md5 , filepath>存储文件名包含“副本”的文件路径,有重复时优先删除private HashMap<String, String> map = new HashMap<>();static int num = 0;/** * 删除指定目录下的所有重复文件 * @param path *            要删除的文件路径 */public void delFile(String path) {File f = new File(path);// 如果给的是一个文件,则继续if (f.isFile()) {doDelFile(f);} else if (f.isDirectory()) {// 拿到它的子文件列表File[] flist = f.listFiles();for (File file : flist) {if (file.isFile()) {// 如果列表项为File,则继续,同上doDelFile(file);} else if (file.isDirectory()) {// 如果列表项为文件夹,递归调用自身delFile(file.getPath());}}}}/** * 删除单个文件 存在副本,先删副本;重复文件名相同,任意删一个 * @param f */public void doDelFile(File f) {// 取得该文件的MD5值String md5 = getMd5(f).toString();if (f.getName().contains("副本")) {map.put(md5, f.getAbsolutePath());}// 如果存放md5值的数组不为空if (md5List.size() > 0) {if (md5List.contains(md5)) {if (f.getName().contains("副本")) {f.delete();num++;System.out.println("\t" + f.getName() + "\t和已有文件重复,已被删除");} else if (!f.getName().contains("副本")) {String tempPath = map.get(md5);if (tempPath != null) {File tp = new File(tempPath);// 删除文件名包含“副本”的tp.delete();num++;System.out.println("\t" + tp.getName() + "\t和已有文件重复,已被删除");} else {// tempPath==null,说明重复的文件和源文件名相同,都不包含“副本”f.delete();num++;System.out.println("\t" + f.getName() + "\t和已有文件重复,已被删除");}}}// 判断该文件是否存在,如果该文件没有被删除,表明没有和该文件相同的文件,则把其md5值存入数组之中if (f.exists()) {md5List.add(md5);}} else {//md5List.seze()==0// 数组为空,表示还没有相同的项,将把其md5值存入数组之中md5List.add(md5);}}/** * 取得文件的Md5值 * @param file *            要计算的文件 * @return MD5值的字符序列 */public static StringBuilder getMd5(File file) {StringBuilder sb = new StringBuilder();StringBuilder fileNotFound = new StringBuilder("系统找不到指定的路径,请重新输入");StringBuilder noAlgorith = new StringBuilder("无法进行Md5加密算法,可能是因为的java虚拟机版本太低");StringBuilder IOError = new StringBuilder("IO错误");try {MessageDigest md5 = MessageDigest.getInstance("MD5"); // 生产MD5类的实例FileInputStream in = new FileInputStream(file);BufferedInputStream bs = new BufferedInputStream(in);byte[] b = new byte[bs.available()]; // 定义数组b为文件不受阻塞的可读取字节数// 将文件以字节方式读取到数组b中while ((bs.read(b, 0, b.length)) != -1) {}md5.update(b); // 执行md5算法for (byte by : md5.digest()) {sb.append(String.format("%02X", by)); // 将生成的字节转化成16进制的字符串}bs.close();} catch (NoSuchAlgorithmException e) {return noAlgorith;} catch (FileNotFoundException e) {return fileNotFound;} catch (IOException e) {return IOError;}return sb;}public static void main(String[] args) {DelExistedFiles df = new DelExistedFiles();df.delFile("D:\\music");System.out.println("操作结束,共删除了\t" + num + "\t个重复文件");}}


我的GitHub     https://github.com/ljheee/JavaUtil