Java实现文件查重去重

  • 前言
  • 大概流程
  • 代码

前言

网上下的一些去重软件不是太慢就是去的不够干净,故用Java编写一个使用

大概流程

① 遍历选定的文件并按照文件长度分组
② 根据md5二次过滤分组
③ 重复文件逻辑删除或物理删除

代码

package file;import org.apache.commons.codec.digest.DigestUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;public class Main {// 配置代码块static {PATH = new String[]{"F:\\test","F:\\test\\test1","F:\\test2"};EXCLUDE_PATH_LIST = new ArrayList(Arrays.asList(
//                "F:\\test\\test","F:\\test\\temp2"));// 删除相关配置TMP_DELETE_PATH = "F:\\testtmp";DELETEDUP = false;
//        DELETEDUP = true;FORCE_DELETEDUP = false;NO_DELETE_INDEX = 0;DELETE_STR = "";// 文件筛选范围相关配置
//        ALLOW_SIZE = Long.MAX_VALUE;ALLOW_SIZE = 10 * 1024 * 1024;SIZE_INTERVAL_MIN = Long.MIN_VALUE;
//        SIZE_INTERVAL_MIN = 0*1024*1024;SIZE_INTERVAL_MAX = Long.MAX_VALUE;
//        SIZE_INTERVAL_MAX = 1*1024*1024;RECURSION = true;// 图片过滤后缀 视频过滤后缀 自定义过滤后缀String CUSTOM_EXTENSIONS = "";String IMAGE_EXTENSIONS = "bmp、jpg、jpeg、png、gif";String VIDEO_EXTENSIONS = "mp4、3gp、avi、flv、mov、rmvb、wmv、mpg、mpeg、rm、ram、swf";POINT_EXTENSIONS =IMAGE_EXTENSIONS + VIDEO_EXTENSIONS +CUSTOM_EXTENSIONS;}/*** 去重文件路径集合*/private static String[] PATH;/*** 排除去重文件路径集合*/private static List EXCLUDE_PATH_LIST;/*** !!!不设置将彻底删除 逻辑删除的文件夹路径*/private static String TMP_DELETE_PATH;/*** 设置 null 不过滤 过滤的后缀集*/private static String POINT_EXTENSIONS;/*** 是否递归子文件夹*/private static boolean RECURSION;/*** 是否删除重复 必须计算了md5的文件才可以删除(除非设置 FORCE_DELETEDUP) 防止误删*/private static boolean DELETEDUP;/*** 谨慎!!! 是否删除强制重复 没有计算md5的文件也可以删除*/private static boolean FORCE_DELETEDUP;/*** 删除重复且路径里包含 deleteStr*/private static String DELETE_STR;/*** 不删除的文件list的索引*/private static int NO_DELETE_INDEX;/*** 为 0表示关闭md5去重 小于 allowSize 字节 才计算md5* 由于计算md5需要加载文件 磁盘限制 效率极低 当重复大文件过多时为了减少md5计算*/private static long ALLOW_SIZE;/*** 文件大小处理区间最小值*/private static long SIZE_INTERVAL_MIN;/*** 文件大小处理区间最大值*/private static long SIZE_INTERVAL_MAX;public static void main(String[] args) {long begin = System.currentTimeMillis();deal(duplicateRemove(PATH));System.err.println(System.currentTimeMillis() - begin);}// 打印 删除private static void deal(Map<String, List<FileMessage>> map) {int num = 1;for (Map.Entry<String, List<FileMessage>> entry : map.entrySet()) {System.err.println(num++ + " ========== " + entry.getKey() + " ==============================");List<FileMessage> value = entry.getValue();for (int i = 0; i < value.size(); i++) {System.err.println(value.get(i));if (DELETEDUP && i != NO_DELETE_INDEX && value.get(i).isCanDelete&& value.get(i).getPath().contains(DELETE_STR)) {Path path2 = Paths.get(value.get(i).getPath());try {if (TMP_DELETE_PATH != null && !"".equals(TMP_DELETE_PATH)) {Files.move(path2, Paths.get(TMP_DELETE_PATH + File.separator+ value.get(i).getPath().replace(":", "-").replace(File.separator, "_")));} else {Files.delete(path2);}} catch (IOException e) {e.printStackTrace();}}}System.err.println("================================");}}// 去重private static Map<String, List<FileMessage>> duplicateRemove(String[] path) {Map<String, List<FileMessage>> map;Map<String, List<FileMessage>> mapResult = new TreeMap<>();List<FileMessage> fileMessageList = new ArrayList<>();searchFile(path, fileMessageList);// 多个文件查找的话 开启重复文件过滤if (path.length > 1) {fileMessageList = new ArrayList<FileMessage>(new LinkedHashSet(fileMessageList));}map = fileMessageList.stream().collect(Collectors.groupingBy(FileMessage::getSize));// md5 去重for (Iterator<Map.Entry<String, List<FileMessage>>> iterator = map.entrySet().iterator(); iterator.hasNext(); ) {Map.Entry<String, List<FileMessage>> entry = iterator.next();List<FileMessage> value = entry.getValue();if (value.size() > 1) {for (int i = 0; i < value.size(); i++) {String s = value.get(i).getPath();String md5 = value.get(i).getSize();if (value.get(i).getSizeLong() < ALLOW_SIZE) {md5 = calculationMD5(s);value.get(i).setCanDelete(true);}value.get(i).setMd5(md5);}if (value != null && value.size() > 0) {Map<String, List<FileMessage>> collect = value.stream().collect(Collectors.groupingBy(FileMessage::getMd5));collect.forEach((k, v) -> {if (v.size() > 1) {mapResult.put(v.get(0).getPath(), v);}});}}}return mapResult;}// 查找文件夹 循环private static void searchFile(String[] filePath, List<FileMessage> fileMessageList) {LinkedList<File> list = new LinkedList<>();for (int i = 0; i < filePath.length; i++) {if (EXCLUDE_PATH_LIST == null || !EXCLUDE_PATH_LIST.contains(filePath[i])) {File file = new File(filePath[i]);if (file.isDirectory()) {list.add(file);while (!list.isEmpty()) {File fileFirst = list.removeFirst();for (File f : fileFirst.listFiles()) {if (EXCLUDE_PATH_LIST == null || !EXCLUDE_PATH_LIST.contains(f.getAbsolutePath())) {if (f.isDirectory()) {if (RECURSION) {list.add(f);}} else {extracted(fileMessageList, f);}}}}} else {extracted(fileMessageList, file);}}}}private static void extracted(List<FileMessage> fileMessageList, File f) {if (POINT_EXTENSIONS == null || isAppointFile(f.getName(), POINT_EXTENSIONS)) {long fileSize = f.length();// 文件大小是否在处理区间if (SIZE_INTERVAL_MIN <= fileSize && SIZE_INTERVAL_MAX >= fileSize) {FileMessage fileMessage = new FileMessage(f.getAbsolutePath(), fileSize + "", f.getName());fileMessageList.add(fileMessage);}}}// 受磁盘影响 md5运算缓慢 少用private static String calculationMD5(String path) {FileInputStream fileInputStream = null;try {fileInputStream = new FileInputStream(path);String md5 = DigestUtils.md5Hex(fileInputStream);return md5;} catch (IOException e) {e.printStackTrace();} finally {try {fileInputStream.close();} catch (IOException e) {e.printStackTrace();}}return null;}// 判断是否是指定文件public static boolean isAppointFile(String fileName, String imageExtension) {String extension = fileName.substring(fileName.lastIndexOf(".") + 1);return imageExtension.contains(extension.toLowerCase());}// 单位换算public static String readableFileSize(String sizeStr) {long size = Long.parseLong(sizeStr);if (size <= 0) {return "0";}final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};int digitGroups = (int) (Math.log10(size) / Math.log10(1024));return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + units[digitGroups];}static class FileMessage {private String path;private String fileName;private String size;private String md5;private boolean isCanDelete = FORCE_DELETEDUP;public FileMessage() {}public FileMessage(String path, String size, String fileName) {this.path = path;this.size = size;this.fileName = fileName;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public String getSize() {return size;}public long getSizeLong() {return Long.parseLong(size);}public void setSize(String size) {this.size = size;}public String getMd5() {return md5;}public void setMd5(String md5) {this.md5 = md5;}public String getFileName() {return fileName;}public void setFileName(String fileName) {this.fileName = fileName;}public boolean isCanDelete() {return isCanDelete;}public void setCanDelete(boolean canDelete) {isCanDelete = canDelete;}@Overridepublic String toString() {return "{" +"path='" + path + '\'' +
//                    ", fileName='" + fileName + '\'' +", size='" + size + '\'' +", size换算='" + readableFileSize(size) + '\'' +", md5='" + md5 + '\'' +", 计算了md5=" + isCanDelete +'}';}@Overridepublic boolean equals(Object obj) {return path.equals(((FileMessage) obj).getPath());}@Overridepublic int hashCode() {return path.hashCode();}}
}

Java实现文件查重去重相关推荐

  1. 用java设计一个文件查重程序,输入两个文本文件,输出两个文本文件的重复率(最长公共子序列的应用)...

    你可以使用java代码来设计一个文件查重程序.首先,你需要读取两个文本文件的内容,将它们存储在字符串变量中.然后,你可以使用最长公共子序列(LCS)算法来计算两个字符串的重复率. LCS算法的实现方法 ...

  2. 学习项目---文件查重

    声明:本项目在deepin系统下vim编译的,利用了jieba分词工具,如果在vs编译的话需要设置文件路径,还需要把GDK转成UTF8,在读的时候用UTF8转成GDK 1.文件查重原理: 1.1中文分 ...

  3. mysql添加用户查重的方法_mysql 开发技巧之JOIN 更新和数据查重/去重

    主要涉及:JOIN .JOIN 更新.GROUP BY HAVING 数据查重/去重 1 INNER JOIN.LEFT JOIN.RIGHT JOIN.FULL JOIN(MySQL 不支持).CR ...

  4. Unity编辑器小工具——文件查重(MD5)

    Unity编辑器小工具--文件查重(MD5) 算法思想: 在Unity中,每一个不同资源.文件所生成MD5码是不同的,但是相同文件,路径不同.文件名不同的同一类文件的MD5码是相同的,所以可以通过生成 ...

  5. centos7 应用笔记: fslint 文件查重

    centos7 应用笔记: fslint 文件查重 fslint 可以用于文件的查重. fslint 扫描的是文件的内容.如果内容一致,则会认为文件一致.而不论文件名是否一致. 安装 fslint # ...

  6. python文件查重_文件查重 我使用的是面向局部敏感的最小哈希签名的方法进行文档查重 联合开发网 - pudn.com...

    文件查重 所属分类:其他 开发工具:Python 文件大小:39KB 下载次数:7 上传日期:2017-12-20 16:45:32 上 传 者:lala_ 说明:  我使用的是面向局部敏感的最小哈希 ...

  7. 文件查重程序 v1.5.4 官网

    Welcome to my blog! <script language="javascript" src="http://avss.b15.cnwg.cn/cou ...

  8. [附源码]计算机毕业设计JAVA文章管理系统查重PPT

    [附源码]计算机毕业设计JAVA文章管理系统查重PPT 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(I ...

  9. java中sql查重跟去重_sql中查重和去重

    在这记录一个实习期间遇到的一个查重和去重的sql语句. 查重语句:(group by 查重) SELECT user_id, count(*) as num FROM 表名 WHERE 条件  GRO ...

最新文章

  1. android 图片圆角 遮罩_Android 自定义View练手Demo(一)实现圆角遮罩效果
  2. halcon相机标定及图像矫正(代码)
  3. C#3.0 Sepcification(中英文对照) (转)
  4. Oracle一些基本术语英汉对照
  5. 系统的性能瓶颈,排查该从哪些方面入手,如何定位?
  6. 华为telnet的两种连接方式
  7. nginx学习笔记之安装
  8. nginx配置在线播放mp4格式视频
  9. 锐捷 linux共享wifi,电脑共享wifi都弱爆了,无线路由器直接共享锐捷
  10. 无法启动此程序 因为计算机中丢失msvcr71.dll,msvcp71.dll丢失怎样修复_电脑提示计算机丢失msvcr71.dll如何解决...
  11. Keep不甘做“工具人”
  12. Web Services 平台元素
  13. Python爬虫之实习生面试问题(一) 爬虫实习生 爬虫面试问题
  14. Linux 2.6下Driver开发的34个变化[转贴]
  15. android studio 小白使用记
  16. e-learning的移动学习:培训从电脑转移到手机,只是媒介的改变?
  17. [SWPU2019]Web3
  18. 《致我们终将逝去的青春》
  19. 神经网络可以解决的问题,神经网络修复技巧论文
  20. Visual Studio中使用EF框架的过程

热门文章

  1. 谈谈snprintf
  2. 主机如何连接到URSim中的客户端接口
  3. Spring Security技术栈开发企业级认证与授权-笔记
  4. 阿里的互联网三高架构是真的牛!腾讯百度根本模仿不来
  5. 《Java基础——break与continue用法详解》
  6. 深度学习中的正则化方法
  7. 2021年江苏高考成绩电话查询,2021年江苏高考具体查分时间 附查分电话方式网址入口...
  8. 单线激光雷达(Lidar)学习三:使用雷达数据/scan转/PointCloud后生成鸟瞰图
  9. 使用nvm安装node报错,Could not retrieve https://nodejs.org/dist/latest/SHASUMS256.txt. Get “https://nodej
  10. Git:git-pull 的用法总结