1.问题:整理之前手机照片,文件发现有很多重复的文件,而且目录比较杂乱,分布零散,就想写一个工具程序,删除重复文件,写完后封装成一个工具类得了。
2.思路:无法根据文件名判断文件是否重复,故使用MD5校验; 遇到有文件夹的,列出下面文件,判断文件还是文件夹,涉及递归。
删除重复文件代码:
/**
* Created by dong on /1/10.
* 删除重复文件 调用时,传入目标路径即可
*/
public class DeleteSameFile {
static List md5List=new ArrayList<>();
static int num = 0;
public static void delFile(String path) throws IOException {
File f = new File(path);
if(f.isFile()){ //如果是一个文件,则继续
isFileAndDeleteFile(f);
}else if(f.isDirectory()){ //如果是一个目录,则拿到它的子文件列表
File[] flist = f.listFiles();
for(File file :flist){
if(file.isFile()){ //列表项为File,则继续,同上
isFileAndDeleteFile(file);
}else if(file.isDirectory()){ //列表项为文件夹,递归调用自身
delFile(file.getPath());
}
}
}
}
private static void isFileAndDeleteFile(File file) throws IOException {
String md5 = MD5Util.getFileMD5String(file).toString(); //取得该文件的MD5值
if (md5List.size() > 0) { //如果存放md5值的数组不为空
for (String s : md5List) {
if (md5.equals(s)) { //如果数组中有了和该文件md5z值相同的项,表明该文件已经存在,删除该文件
file.delete();
num++;
Log.i("size", "文件:" + file.getName() + "和已有文件重复,已被删除");
}
}
if (file.exists()) { //判断该文件是否存在,如果该文件没有被删除,说明没有和该文件相同的文件,则把其md5值存入数组之中
md5List.add(md5);
}
}
}
}
MD5校验工具:
public class MD5Util {
/**
* 默认的密码字符串组合,用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合
*/
protected static char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
protected static MessageDigest messagedigest = null;
static {
try {
messagedigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
public static String getFileMD5String(File file) throws IOException {
InputStream fis;
fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
int numRead = 0;
while ((numRead = fis.read(buffer)) > 0) {
messagedigest.update(buffer, 0, numRead);
}
fis.close();
return bufferToHex(messagedigest.digest());
}
private static String bufferToHex(byte bytes[]) {
return bufferToHex(bytes, 0, bytes.length);
}
private static String bufferToHex(byte bytes[], int m, int n) {
StringBuffer stringbuffer = new StringBuffer(2 * n);
int k = m + n;
for (int l = m; l < k; l++) {
appendHexPair(bytes[l], stringbuffer);
}
return stringbuffer.toString();
}
private static void appendHexPair(byte bt, StringBuffer stringbuffer) {
char c0 = hexDigits[(bt & 0xf0) >> 4];// 取字节中高 4 位的数字转换
// 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同
char c1 = hexDigits[bt & 0xf];// 取字节中低 4 位的数字转换
stringbuffer.append(c0);
stringbuffer.append(c1);
}
}