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

        一直以来收藏的经典歌曲已经有好几百首,而且不同时期喜欢听不同的,在主文件夹下有些重复的.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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值