Java怎么把文件名相同的输出_将给定目录去除重复文件,或打印输出重复文件列表,根据文件的MD5,忽略文件的文件名是否相同。...

1.[代码][Java]代码

package com.goofus.tool;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.math.BigInteger;

import java.security.MessageDigest;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Set;

import java.util.Map.Entry;

/**

* 将给定目录去除重复文件,或打印输出重复文件列表,根据文件的MD5,忽略文件的文件名是否相同。

*

* 删除重复的文件,优先保留路径最短的那个文件。

*

* 仅适用一般情况,对于需要重复存在的情况慎用。

*

*
例子:

*

* 1)默认只打印输出重复文件列表,不删除重复文件,如:C:\\>java com.goofus.tool.FileRepeat D:\\test\\aa

*

* 或:C:\\>java com.goofus.tool.FileRepeat D:\\test\\aa -m:list

*

* 2)删除重复文件,如:C:\\>java com.goofus.tool.FileRepeat D:\\test\\aa -m:clear

*

* @author goofus/Administrator

* Jul 14, 2014

*/

public class FileRepeat {

//文件实例作为KEY,文件MD5值作为VALUE

private final static Map FILE_MD5_MAP = new HashMap();

//重复文件寄存器;文件MD5值作为KEY,重复文件的列表作为VALUE

private final static Map> FILE_REPEATED_MAP = new HashMap>();

//模式;默认输出重复文件列表

private static String HANDLE_MODE = "list";

/**

* @param args

*/

public static void main(String[] args) {

long s = System.currentTimeMillis();

if(null == args || args.length < 1) {

System.out.println("输入正确的参数,如:C:\\>java FileRepeat D:\\test\\aa");

System.exit(-1);

}

String filePath = args[0];

File dir = new File(filePath);

if(!dir.isDirectory() || !dir.exists()) {

System.out.println("输入正确的目录");

System.exit(-1);

}

String args1 = args.length > 1 ? args[1] : null;

if(null != args1) {

if(args1.startsWith("-m:")) {

String mode = args1.replaceAll("-m:", "");

if(null == mode || ("list".equalsIgnoreCase(mode) && !"clear".equalsIgnoreCase(mode))){

System.out.println("-m:可选项:list、clear");

System.exit(-1);

}

HANDLE_MODE = mode;

}else {

System.out.println("输入正确的参数,如:C:\\>java com.goofus.tool.FileRepeat D:\\test\\aa -m:clear");

System.exit(-1);

}

}

int tally = 0;

computeFileMd5(dir);

handleRepeat();

tally = deleteForRepeat();

//打印输出重复文件列表

if("list".equalsIgnoreCase(HANDLE_MODE)){

Set>> rSet = FILE_REPEATED_MAP.entrySet();

for(Iterator>> it = rSet.iterator(); it.hasNext();){

Entry> entry = it.next();

String key = entry.getKey();

List files = entry.getValue();

if(null != files && files.size() > 0){

StringBuffer fPath = new StringBuffer();

for(int a=0,al=files.size(); a

File f = files.get(a);

if(a > 0) fPath.append(",");

fPath.append(f.getAbsolutePath());

}

System.out.println("MD5值为:" + key + " 的重复文件:" + fPath);

}

}

}else if(tally < 1){

System.out.println("没有重复的文件。");

}

System.out.println("删除了" + tally + "个重复文件,耗时:" + (System.currentTimeMillis() - s) + "毫秒。");

}

private static void computeFileMd5(File dir){

if(null == dir) return ;

File[] files = dir.listFiles();

if(null != files && files.length > 0){

for(File f : files){

if(f.isDirectory()){

computeFileMd5(f);

}else{

FILE_MD5_MAP.put(f, getMd5ForFile(f));

}

}

}

}

private static void handleRepeat(){

if(FILE_MD5_MAP.size() < 2) return ;

Set> set = FILE_MD5_MAP.entrySet();

for(Iterator> it = set.iterator(); it.hasNext();){

Entry entry = it.next();

if(FILE_REPEATED_MAP.containsKey(entry.getValue())){

//文件的MD5值已经作为KEY存在于重复寄存器中,则认为该文件存在重复,直接记入重复寄存器

addToRepeatedMap(entry);

}else{

//否则,迭代比较是否存在重复文件

for(Iterator> it2 = set.iterator(); it2.hasNext();){

Entry entry2 = it2.next();

if(!entry.getKey().equals(entry2.getKey()) && entry.getValue().equals(entry2.getValue())){

//存在重复的文件,先记入集合,等待进一步处理

if(FILE_REPEATED_MAP.containsKey(entry.getValue())){

addToRepeatedMap(entry);

}else{

List value = new ArrayList();

value.add(entry.getKey());

FILE_REPEATED_MAP.put(entry.getValue(), value);

}

break;

}

}

}

}

}

private static int deleteForRepeat(){

int c = 0;

//去重,仅保留一个

if(FILE_REPEATED_MAP.size() > 0 && "clear".equalsIgnoreCase(HANDLE_MODE)){

Set>> rSet = FILE_REPEATED_MAP.entrySet();

for(Iterator>> it = rSet.iterator(); it.hasNext();){

Entry> entry = it.next();

String key = entry.getKey();

List files = entry.getValue();

if(null != files && files.size() > 0){

System.out.println("【保留】保留MD5值为:" + key + " 的重复文件之一:" + files.get(0).getAbsolutePath());

for(int a=1,al=files.size(); a

File f = files.get(a);

String fPath = f.getAbsolutePath();

boolean success = f.delete();

if(success) {

c++;

System.out.println("【成功】删除MD5值为:" + key + " 的重复文件之一:" + fPath);

}else{

System.out.println("【失败】删除MD5值为:" + key + " 的重复文件之一:" + fPath);

}

}

}

}

}

return c;

}

private static void addToRepeatedMap(Entry entry) {

int depth = computeDepth(entry.getKey());

if(depth < computeDepth(FILE_REPEATED_MAP.get(entry.getValue()).get(0))){

//路径最短放在第1个,去重时将被保留

FILE_REPEATED_MAP.get(entry.getValue()).add(0, entry.getKey());

}else{

FILE_REPEATED_MAP.get(entry.getValue()).add(entry.getKey());

}

}

private static int computeDepth(File f){

String path = convertPath(f.getAbsolutePath());

String[] paths = path.split("/");

if(null != paths) return paths.length;

else return 999;

}

private static String convertPath(String path) {

if(null != path)

return path.replaceAll("\\\\", "/");

else return "";

}

/**

* 计算文件的MD5值

* @param f 文件

* @return MD5值

*/

private static String getMd5ForFile(File f) {

String rtn = "";

if(null == f || f.isDirectory() || !f.exists()) return rtn;

FileInputStream fis = null;

try {

MessageDigest md = MessageDigest.getInstance("MD5");

fis = new FileInputStream(f);

byte[] buffer = new byte[8192];

int length;

while ((length = fis.read(buffer)) != -1) {

md.update(buffer, 0, length);

}

BigInteger bi = new BigInteger(1, md.digest());

rtn = bi.toString(16);

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if (fis != null) fis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

return rtn;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值