可以使用MD5算法来实现文件去重,因为它可以接受任意大小的数据并输出固定长度的哈希值。所以两个不一样的文件一般情况下使用MD5计算出来的hash值是不可能会相等的。

所以一旦两个文件计算出来的hash值相同那么他们的文件就是相同的。

这时文件上传的一个例子,先使用md5算法计算文件的hash值,再检测我们磁盘是否有相同的文件名的文件,如果有那我们就不上传直接返回访问路径,如果没有才上传

    @Overridepublic String uploadFile(MultipartFile file, String path) {try {// 获取文件md5值String md5 = FileUtils.getMd5(file.getInputStream());// 获取文件扩展名String extName = FileUtils.getExtName(file.getOriginalFilename());// 重新生成文件名String fileName = md5 + extName;System.out.println("filename  "+fileName);// 判断文件是否已存在if (!exists(path + fileName)) {// 不存在则继续上传upload(path, fileName, file.getInputStream());}// 返回文件访问路径return getFileAccessUrl(path + fileName);} catch (Exception e) {e.printStackTrace();throw new BizException("文件上传失败");}}

我这就先看一下MD5得到Hash值的逻辑

public static String getMd5(InputStream inputStream) {try {MessageDigest md5 = MessageDigest.getInstance("md5");byte[] buffer = new byte[8192];int length;while ((length = inputStream.read(buffer)) != -1) {md5.update(buffer, 0, length);}return new String(Hex.encodeHex(md5.digest()));} catch (Exception e) {e.printStackTrace();return null;} finally {try {if (inputStream != null) {inputStream.close();}} catch (IOException e) {e.printStackTrace();}}}

这里使用的是JDK自带的MD5算法,也可以替换成其他库提供的MD5算法。讲一下得到MD5算法摘要的大致逻辑,当然不看 得到MD5算法摘要的的逻辑也是可以的,没有影响

先传入我们要得到的算法名称

MessageDigest.getInstance("md5");

MessageDigest.getInstance又会调用这个方法

GetInstance.Instance instance = GetInstance.getInstance("MessageDigest",MessageDigestSpi.class, algorithm);

这里是先得到所有的算法类提供商,再在提供商列表中查找第一个支持该算法的提供商提供的服务类,如果这个服务类能够提供指定的clazz的实例就直接将这个Instance返回,如果不能就找下一个能提供该算法的提供商看行不行。

我们这里的clazz就是MessageDigestSpi类,该类为MessageDigest类定义服务提供者接口(Service Provider Interface, SPI),该类提供消息摘要算法的功能,如MD5或SHA。消息摘要是安全的单向哈希函数,它接受任意大小的数据并输出固定长度的哈希值。

 public static Instance getInstance(String type, Class<?> clazz,String algorithm) throws NoSuchAlgorithmException {// in the almost all cases, the first service will work// avoid taking long path if soProviderList list = Providers.getProviderList();Service firstService = list.getService(type, algorithm);if (firstService == null) {throw new NoSuchAlgorithmException(algorithm + " " + type + " not available");}NoSuchAlgorithmException failure;try {return getInstance(firstService, clazz);} catch (NoSuchAlgorithmException e) {failure = e;}for (Service s : list.getServices(type, algorithm)) {if (s == firstService) {// do not retry initial failed servicecontinue;}try {return getInstance(s, clazz);} catch (NoSuchAlgorithmException e) {failure = e;}}throw failure;}

最后返回我们期望的消息摘要算法MessageDigest。除了有MD5以外还有SHA1等等算法可以选择

MessageDigest的方法:

  • getInstance 得到算法摘要
  • update 处理这些数据
  • digest 转换并返回结果,也是字节数组

在校验文件重复性的时候,我们最后一步就是将MD5校验返回的字节数组编码成16进制的字符数组,然后用这个字符数组转换为字符串作为我们文件的名字,如果以后还有同样的文件被上传了,会对比是否有文件名相同的文件。

因为一个字节需要2个16进制数来表示,所以字符数组的大小是字节数组的大小的2倍

   public static String encodeHex(byte[] byteArray) {// 首先初始化一个字符数组,用来存放每个16进制字符char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F' };// new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))char[] resultCharArray =new char[byteArray.length * 2];// 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去int index = 0;for (byte b : byteArray) {resultCharArray[index++] = hexDigits[b>>> 4 & 0xf];resultCharArray[index++] = hexDigits[b& 0xf];}// 字符数组组合成字符串返回return new String(resultCharArray);}

对于计算文件的MD5 的Hash值时我们可以像这样使用基础的InputStrem

  MessageDigest md5 = MessageDigest.getInstance("md5");byte[] buffer = new byte[8192];int length;while ((length = inputStream.read(buffer)) != -1) {md5.update(buffer, 0, length);}byte[] resultByteArray = MD5.digest();

也可以使用DigestInputStream

         MessageDigest messageDigest =MessageDigest.getInstance("MD5");// 使用DigestInputStreamDigestInputStream  digestInputStream = new DigestInputStream(inputStream,messageDigest);// read的过程中进行MD5处理,直到读完文件byte[] buffer =new byte[bufferSize];while (digestInputStream.read(buffer) > 0);// 获取最终的MessageDigestmessageDigest= digestInputStream.getMessageDigest();byte[] resultByteArray = messageDigest.digest();

使用md5来实现文件去重相关推荐

  1. python对文件夹内文件去重

    昨天无聊写了一个百度图片爬虫,测试了一下搜索"斗图".一下给我下了3000多个图片,关键是有一半以上重复的.what a fuck program ! 好吧,今天写一个文件去重功能 ...

  2. python去重txt文本_Python 文件去重(转载)

    原博文 2020-02-14 13:20 − Python实现的txt文件去重功能示例 更新时间:2018年07月07日 09:00:36 作者:人饭子 我要评论 这篇文章主要介绍了Python实现的 ...

  3. php读取文件和读取redis,PHP结合redis实现大文件去重

    本篇文章主要内容是用PHP多个进程配合redis的有序集合实现大文件去重,感兴趣的朋友可以学习一下. 1.对一个大文件比如我的文件为 -rw-r--r-- 1 ubuntu ubuntu 9.1G M ...

  4. php redis 集合返回多条,详解PHP多个进程配合redis的有序集合实现大文件去重

    1.对一个大文件比如我的文件为 -rw-r--r-- 1 ubuntu ubuntu 9.1G Mar 1 17:53 2018-12-awk-uniq.txt 2.使用split命令切割成10个小文 ...

  5. 【数据挖掘】利用md5查找重复文件

    [数据挖掘]利用md5查找重复文件 电脑经过长时间的使用,难免会存留许多重复文件.这些重复文件往往四散在各处,其文件名.修改时间等信息都有改动,这对我清理重复文件造成了困扰.尽管重复文件已经有了诸多修 ...

  6. 根据文件MD5删除重复文件

    根据文件MD5删除重复文件,仅保留一份文件: ```shell find . -type f -exec md5sum {} \; | sort -k 1 | awk 'a[$1]++{print $ ...

  7. 单向散列函数概述并基于MD5算法对文件哈希值实时监测

    1.如何验证文件是否被修改过 只生成一个指纹文件,对指纹文件进行验证 当已经存储的文件被修改之后,指纹文件就会跟着变化,即生成一个单向散列函数 任意长度的数据都对应固定长度的散列值–减少匹配开销 散列 ...

  8. c语言压缩并加密算法,C语言压缩文件和用MD5算法校验文件完整性的实例教程

    使用lzma SDK对7z文件简单解压缩有时候我们只需要单纯对lzma算法压缩的7z文件进行解压,有时需要在嵌入式设备上解压,使用p7zip虽然支持多种格式,但是不容易裁剪,使用lzma SDK是首选 ...

  9. python文件去重软件_Python实现的txt文件去重功能示例

    本文实例讲述了Python实现的txt文件去重功能.分享给大家供大家参考,具体如下: # -*- coding:utf-8 -*- #! python2 import shutil a=0 readD ...

最新文章

  1. 软件测试工程师职业介绍和规划
  2. 2018-3-6论文-网络评论中非结构化信息的应用于研究------(语义矩离)
  3. 网络慢是带宽不足?优化网络带宽的5个小窍门
  4. cisco 恢复出厂设置
  5. Swoole 自定义项目初始化事件处理的实现
  6. [考试]20150528
  7. python re findall 效率_python re模块findall()详解
  8. xheditor可视化富文本编辑器
  9. table模板标签,批量多选失效的问题,tr td结构多选框失效相关问题
  10. STM32F303VCT6(数据表) ARM Cortex M4,微控制器
  11. 2023北京理工大学计算机考研信息汇总
  12. python 提取元组中的值_如何从Python元组中提取数据?
  13. 【机器学习】机器学习在爱奇艺视频分析理解中的实践
  14. Android 长按APP图标弹出快捷方式(shortcuts)
  15. 水仙花数的判断(JAVA)
  16. 深入学习Gremlin(5):查询路径path
  17. 当代最值得收藏的画家作品_名人名画推荐,值得收藏的当代画家作品
  18. 奥格斯堡水利系统被列入教科文组织世界遗产名录
  19. 常见几种开关电源工作原理及电路图
  20. css的div,span,img,a,map等一些常见标签使用 回顶设置

热门文章

  1. 读取扭力计的COM口数据
  2. FreeBSD使用总结
  3. 根据WADL生成REST风格WebService的客户端代码
  4. elementUI el-table设置fixed后,竖向滚动条滚动到底部表格错位的问题(修改源码)
  5. cadence自动生成铺铜_Cadence Allegro简易手册连载7:内层及铺铜
  6. vs2019 自定义工具错误: 未能生成文件: 系统找不到指定的文件。 (异常来自 HRESULT:0x80070002)
  7. XML文件介绍,这也太简单了
  8. STM32CUBEMX(9)--ADC通过轮询方式读取,USART打印
  9. Linux 代理 http 和 socks 配置区别
  10. AES128加密解密