1.問(wèn)題:整理之前手機(jī)照片愕提,文件發(fā)現(xiàn)有很多重復(fù)的文件馒稍,而且目錄比較雜亂,分布零散浅侨,就想寫(xiě)一個(gè)工具程序纽谒,刪除重復(fù)文件,寫(xiě)完后封裝成一個(gè)工具類(lèi)得了如输。
2.思路:無(wú)法根據(jù)文件名判斷文件是否重復(fù)鼓黔,故使用MD5校驗(yàn); 遇到有文件夾的不见,列出下面文件澳化,判斷文件還是文件夾,涉及遞歸稳吮。
刪除重復(fù)文件代碼:
/**
* Created by dong on 2017/1/10.
* 刪除重復(fù)文件 調(diào)用時(shí)缎谷,傳入目標(biāo)路徑即可
*/
public class DeleteSameFile {
static List<String> md5List=new ArrayList<>();
static int num = 0;
public static void delFile(String path) throws IOException {
File f = new File(path);
if(f.isFile()){ //如果是一個(gè)文件,則繼續(xù)
isFileAndDeleteFile(f);
}else if(f.isDirectory()){ //如果是一個(gè)目錄灶似,則拿到它的子文件列表
File[] flist = f.listFiles();
for(File file :flist){
if(file.isFile()){ //列表項(xiàng)為File列林,則繼續(xù),同上
isFileAndDeleteFile(file);
}else if(file.isDirectory()){ //列表項(xiàng)為文件夾酪惭,遞歸調(diào)用自身
delFile(file.getPath());
}
}
}
}
private static void isFileAndDeleteFile(File file) throws IOException {
String md5 = MD5Util.getFileMD5String(file).toString(); //取得該文件的MD5值
if (md5List.size() > 0) { //如果存放md5值的數(shù)組不為空
for (String s : md5List) {
if (md5.equals(s)) { //如果數(shù)組中有了和該文件md5z值相同的項(xiàng)希痴,表明該文件已經(jīng)存在,刪除該文件
file.delete();
num++;
Log.i("size", "文件:" + file.getName() + "和已有文件重復(fù),已被刪除");
}
}
if (file.exists()) { //判斷該文件是否存在春感,如果該文件沒(méi)有被刪除润梯,說(shuō)明沒(méi)有和該文件相同的文件,則把其md5值存入數(shù)組之中
md5List.add(md5);
}
}
}
}
MD5校驗(yàn)工具:
public class MD5Util {
/**
* 默認(rèn)的密碼字符串組合,用來(lái)將字節(jié)轉(zhuǎn)換成 16 進(jìn)制表示的字符,apache校驗(yàn)下載的文件的正確性用的就是默認(rèn)的這個(gè)組合
*/
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];// 取字節(jié)中高 4 位的數(shù)字轉(zhuǎn)換
// 為邏輯右移纺铭,將符號(hào)位一起右移,此處未發(fā)現(xiàn)兩種符號(hào)有何不同
char c1 = hexDigits[bt & 0xf];// 取字節(jié)中低 4 位的數(shù)字轉(zhuǎn)換
stringbuffer.append(c0);
stringbuffer.append(c1);
}
}