您现在的位置是:亿华云 > 数据库
Java 如何校验两个文件内容是相同的?
亿华云2025-10-05 12:14:36【数据库】9人已围观
简介今天做文件上传功能,需求要求文件内容相同的不能重复上传。感觉这个需求挺简单的就交给了一位刚入行的新同学。等合并代码的时候发现这位同学居然用文件名称相同和文件大小相同作为两个文件相同的依据。这种条件判断
今天做文件上传功能,何校需求要求文件内容相同的验两不能重复上传。感觉这个需求挺简单的个文就交给了一位刚入行的新同学。等合并代码的容相时候发现这位同学居然用文件名称相同和文件大小相同作为两个文件相同的依据。这种条件判断靠谱吗?何校
从概率上来说遇到两个文件名称和大小都一样的概率确实太小了。这种判断放在生产环境中也可以稳定的验两跑上一阵子,不过即使再低的个文可能性也是有可能的,如果能做到100%就好了。容相
文件摘要校验
我相信同学们都下载过一些好心人开发的何校小工具,有些小工具会附带一个校验器让你校验附带提供的验两checksum值,防止有人恶意篡改小工具,个文保证小工具可以放心使用。容相
文件Hash校验
如果两个文件的何校内容相同,那么它们的验两摘要应该是相同的。这个原理能不能帮助我们鉴定两个文件是个文否相同呢?
Java实现文件摘要
带着这个疑问,我写了一个文件摘要提取工具类:
/** * 提取文件 checksum * * @param path 文件全路径 * @param algorithm 算法名 例如 MD5、SHA-1、服务器租用SHA-256等 * @return checksum * @throws NoSuchAlgorithmException the no such algorithm exception * @throws IOException the io exception */ public static String extractChecksum(String path, String algorithm) throws NoSuchAlgorithmException, IOException { // 根据算法名称初始化摘要算法 MessageDigest digest = MessageDigest.getInstance(algorithm); // 读取文件的所有比特 byte[] fileBytes = Files.readAllBytes(Paths.get(path)); // 摘要更新 digest.update(fileBytes); //完成哈希摘要计算并返回特征值 byte[] digested = digest.digest(); // 进行十六进制的输出 return HexUtils.toHexString(digested); }接下来做几组对照试验来证明猜想。
内容不变
首先要证明一个文件在内容不变的情况下摘要是否有变化,多次执行下面的代码,断言始终都是true。
String path = "C:\\Users\\s1\\IdeaProjects\\demo\\src\\main\\resources\\application.yml"; String checksum = extractChecksum(path, "SHA-1"); String hash = "6bf4d6c101b4a7821226d3ec1f8d778a531bf265"; Assertions.assertEquals(hash,checksum);而且我把文件名改成application-dev.yml,甚至application-dev.txt摘要都是相同的。我又把yml文件的内容作了改动,断言就false了。这证明了单个文件的情况下,内容不变,hash是不变的。
文件复制
我把yml文件复制了一份,改了文件名称和类型,不改变内容并存到了另一个目录中,来测试一下它们的摘要是否有变化。
String path1 = "C:\\Users\\s1\\IdeaProjects\\demo\\src\\main\\resources\\application.yml"; String path2 = "C:\\Users\\s1\\IdeaProjects\\demo\\src\\main\\resources\\templates\\application-dev.txt"; String checksum1 = extractChecksum(path1, "SHA-1"); String checksum2 = extractChecksum(path2, "SHA-1"); String hash = "6bf4d6c101b4a7821226d3ec1f8d778a531bf265"; Assertions.assertEquals(hash,checksum1); Assertions.assertEquals(hash,checksum2);结果断言通过,不过改变了其中一个文件的内容后断言就不通过了。
新建空文件
这里的服务器托管新建空文件指的是没有进行任何操作的新建的空文件。
新建的空文件会根据特定的算法返回一个固定值,比如SHA-1算法下的空文件值是:
da39a3ee5e6b4b0d3255bfef95601890afd80709结论
通过实验证明了:
在相同算法下,任何新建空文件的摘要值都是固定的。
任何两个内容相同的文件的摘要值都是相同的,和路径、文件名、文件类型无关。
文件的摘要值会随着文件内容的改变而改变。
文件摘要运用
根据上面的结论,文件摘要是可以防止同样内容的文件重复提交的, 存储的站群服务器时候不但要存储文件的路径,还要存储文件的摘要值,可能需要注意新建空文件的的固定摘要问题。另外在Java12中提供了新的API来处理文件内容重复问题,有兴趣的可以研究一下。文件摘要除了防篡改和去重之外,你知道还有其它什么用途吗?欢迎同学们留言讨论。
本文转载自微信公众号「码农小胖哥」,可以通过以下二维码关注。转载本文请联系码农小胖哥公众号。
很赞哦!(23)
相关文章
- 5. 四种状态过后,域名管理机构释放域名给公众注册。
- 为什么Python这么慢?
- 手把手教你写网络爬虫(7):URL去重
- 10行代码-利用Python做一个微信聊天机器人(简单易懂)
- 国际域名转移的费用和处理步骤是什么?
- 如何使用Spring Cloud构建微服务架构?(文末赠书)
- Java架构师面试题全分享,你离架构师还有多远?
- Python智能程序,微信遥控电脑,无需任何其它硬件!
- 当投资者经过第二阶段的认真学习之后又充满了信心,认为自己可以在市场上叱咤风云地大干一场了。但没想到“看花容易绣花难”,由于对理论知识不会灵活运用.从而失去灵活应变的本能,就经常会出现小赢大亏的局面,结果往往仍以失败告终。这使投资者很是困惑和痛苦,不知该如何办,甚至开始怀疑这个市场是不是不适合自己。在这种情况下,有的人选择了放弃,但有的意志坚定者则决定做最后的尝试。
- 详细的多维度测评,看看哪个 Python 版本速度最快!