Java实现快速文件查重功能
/*** 重复文件管理器*/
public class RepeatFileManager {private static final String EMPTY_FILE = "empty_file"; //空文件private Map<Long, String> mFileSizeMap = new HashMap<>(); //保存文件大小private Map<String, String> mFileHashMap = new HashMap<>(); //保存文件hashprivate Map<String, List<String>> mRepeatFileMap = new HashMap<>(); //最终重复文件private boolean mCanceled;private OnRepeatStatsListener onRepeatStatsListener;public void start(final File dir) {new Thread() {public void run() {mCanceled = false;mFileSizeMap.clear();mFileHashMap.clear();mRepeatFileMap.clear();calc(dir);if (onRepeatStatsListener != null) {onRepeatStatsListener.onRepeatStatsFinished(mRepeatFileMap);}};}.start();}private void calc(File dir) {File[] files = dir.listFiles();if (files != null && files.length > 0) {for (File file : files) {if (file.isDirectory()) {calc(file);continue;} if (file.length() == 0) {//空文件List<String> pathList = mRepeatFileMap.get(EMPTY_FILE);if (pathList == null) {pathList = new ArrayList<>();mRepeatFileMap.put(EMPTY_FILE, pathList);}pathList.add(file.getAbsolutePath());} else {if(mFileSizeMap.containsKey(file.length())){//大小重复,计算文件散列String path = mFileSizeMap.get(file.length());if (!mFileHashMap.values().contains(path)) {String firstHash = calcFileKey(new File(path));if (firstHash != null) {mFileHashMap.put(firstHash, path);}}String hash = calcFileKey(file);if (hash != null) {if (mFileHashMap.containsKey(hash)) {//散列重复,保存文件路径List<String> pathList = mRepeatFileMap.get(hash);if (pathList == null) {pathList = new ArrayList<>();pathList.add(mFileHashMap.get(hash));mRepeatFileMap.put(hash, pathList);}pathList.add(file.getAbsolutePath());} else {mFileHashMap.put(hash, file.getAbsolutePath());}}}else {mFileSizeMap.put(file.length(), file.getAbsolutePath());}}if (mCanceled) {break;}}}}/*** 计算文件唯一散列值* @param file* @return*/private static String calcFileKey(File file) {String md5 = calcFileMd5(file);String crc32 = calcFileCRC32(file);if (!md5.isEmpty() && !crc32.isEmpty()) {return md5 + "_" + crc32;} else {return null;}}/*** 获取文件md5* * @param file* @return*/private static String calcFileMd5(File file) {if (!file.isFile()) {return "";}MessageDigest digest = null;FileInputStream in = null;byte buffer[] = new byte[1024];int len;try {digest = MessageDigest.getInstance("MD5");in = new FileInputStream(file);while ((len = in.read(buffer, 0, 1024)) != -1) {digest.update(buffer, 0, len);}in.close();return byteToHex(digest.digest());} catch (Exception e) {e.printStackTrace();}return "";}private static String byteToHex(byte[] data) {if (data != null) {StringBuilder builder = new StringBuilder();for (int i = 0; i < data.length; i++) {int v = data[i] & 0xFF;builder.append(String.format("%02x", v));}return builder.toString();} else {return null;}}/*** 获取文件crc32* @param file* @return*/private static String calcFileCRC32(File file) {BufferedInputStream in = null;try {in = new BufferedInputStream(new FileInputStream(file));CRC32 crc = new CRC32();byte[] bytes = new byte[1024];int cnt;while ((cnt = in.read(bytes)) != -1) {crc.update(bytes, 0, cnt);}return Long.toHexString(crc.getValue());} catch (Exception e) {e.printStackTrace();} finally {try {if (in != null) {in.close();}} catch (IOException e) {e.printStackTrace();}}return "";}public void testCalc(File file) {System.out.println(calcFileMd5(file));}public Map<String, List<String>> getRepeatFiles() {return mRepeatFileMap;}public void setOnRepeatStatsListener(OnRepeatStatsListener onRepeatStatsListener) {this.onRepeatStatsListener = onRepeatStatsListener;}public interface OnRepeatStatsListener {void onRepeatStatsFinished(Map<String, List<String>> repeatFiles);}
}
public class RepeatFileDemo {public static void main(String[] args) {RepeatFileManager rfm = new RepeatFileManager();final long startTime = System.currentTimeMillis();rfm.setOnRepeatStatsListener(new RepeatFileManager.OnRepeatStatsListener() {@Overridepublic void onRepeatStatsFinished(Map<String, List<String>> repeatFiles) {long useTime = System.currentTimeMillis() - startTime;System.out.println("用时:" + useTime /1000f + "秒");for(Map.Entry<String, List<String>> entry: repeatFiles.entrySet()){System.out.println(entry.getKey());for(String path: entry.getValue()){System.out.println(path);}System.out.println();}}});rfm.start(new File("Z:\\娱乐"));}
}
Java实现快速文件查重功能相关推荐
- 用java设计一个文件查重程序,输入两个文本文件,输出两个文本文件的重复率(最长公共子序列的应用)...
你可以使用java代码来设计一个文件查重程序.首先,你需要读取两个文本文件的内容,将它们存储在字符串变量中.然后,你可以使用最长公共子序列(LCS)算法来计算两个字符串的重复率. LCS算法的实现方法 ...
- Java实现文件查重去重
Java实现文件查重去重 前言 大概流程 代码 前言 网上下的一些去重软件不是太慢就是去的不够干净,故用Java编写一个使用 大概流程 ① 遍历选定的文件并按照文件长度分组 ② 根据md5二次过滤分组 ...
- 学习项目---文件查重
声明:本项目在deepin系统下vim编译的,利用了jieba分词工具,如果在vs编译的话需要设置文件路径,还需要把GDK转成UTF8,在读的时候用UTF8转成GDK 1.文件查重原理: 1.1中文分 ...
- 基于Python3.x pandas实现大疫情的查重功能
基于Python3.x pandas实现大疫情的查重功能 https://blog.csdn.net/ky200904020/article/details/88693219 系统使用 win7 32 ...
- 计算机类的毕业论文是怎么查重的,论文检测软件是如何实现查重功能的
之所以人们在写完论文之后会使用知网检测软件来检测文章的原创度,是因为重复率过高的论文是无法符合要求的.那么,我们日常生活中所使用的论文检测软件是如何实现查重功能的呢?现在,就让我详细的为大家进行介绍. ...
- Unity编辑器小工具——文件查重(MD5)
Unity编辑器小工具--文件查重(MD5) 算法思想: 在Unity中,每一个不同资源.文件所生成MD5码是不同的,但是相同文件,路径不同.文件名不同的同一类文件的MD5码是相同的,所以可以通过生成 ...
- centos7 应用笔记: fslint 文件查重
centos7 应用笔记: fslint 文件查重 fslint 可以用于文件的查重. fslint 扫描的是文件的内容.如果内容一致,则会认为文件一致.而不论文件名是否一致. 安装 fslint # ...
- python文件查重_文件查重 我使用的是面向局部敏感的最小哈希签名的方法进行文档查重 联合开发网 - pudn.com...
文件查重 所属分类:其他 开发工具:Python 文件大小:39KB 下载次数:7 上传日期:2017-12-20 16:45:32 上 传 者:lala_ 说明: 我使用的是面向局部敏感的最小哈希 ...
- 文件查重程序 v1.5.4 官网
Welcome to my blog! <script language="javascript" src="http://avss.b15.cnwg.cn/cou ...
最新文章
- 时间序列预测实例(prophet的血泪史)
- python正则查找_python正则查找
- nx set 怎么实现的原子性_正确地使用Redis的SETNX实现锁机制
- 出现ping: unknown host www.baidu.com 问题解决
- C语言分治算法求中位数,【算法复习】分治算法
- 3.7.5 - Modifying Strings
- python学习笔记__Python的安装
- [BootStrap学习随笔] 起步、布局容器和栅格式布局
- 无线通信定位一体化进展及其在煤矿井下应用分析
- PC端和移动端的区别你知道吗?
- 普乐郡——回乐县(城市记忆7)
- 如何快速转发csdn博客?
- 车辆VIN码的校验算法
- eclipse Java Web项目自定义访问项目名称
- 守望先锋世界观架构 ——(一款好的游戏是怎么来的)
- 嵌入式与通用计算机的相同点,嵌入式计算机与通用计算机的区别与联系
- 2022年R1快开门式压力容器操作理论题库及在线模拟考试
- canvas 绘制图片
- 基于STM32智能小车->红外寻迹篇
- IDE SATA SCSI 三种常见硬盘之间的区别(二)