我正在寻找一种简单的方法来检测目录中的文件在重新启动之间是否已更改,以避免不必要的同步。在 java 8 库中执行此操作的最简单方法是什么?我应该对每个文件的 md5 摘要进行异或,还是对每个文件的校验和进行异或?
ATM 我们不需要处理进入子目录的情况。
此外,我们不应该使用操作系统事件来检测此更改,因为检测方法只会在启动时调用。目录中的文件数量可能会在应用程序的不同版本之间发生变化,但这些文件通常不会在重新启动之间发生变化。
这看起来像一个相关的帖子: https://crypto.stackexchange.com/questions/1368/is-it-a-good-idea-to-use-bitwise-xor-on-a-set-of-md5-sums
最佳答案
这取决于你所说的“简单”是什么意思。
一方面,您可以利用文件时间戳。但问题是时间戳可能会产生误导:
根据时间戳进行的检查可能受到时钟偏差问题的影响。 (这取决于涉及哪些时钟,以及如何管理时钟。)
文件时间戳可能会被重置(例如由“root”用户),使文件看起来没有更改。
在不实际更改文件的情况下更改“已修改”文件时间戳是很简单的;例如
触摸
。
另一方面,如果您使用校验和,则会遇到其他问题:
计算文件校验和需要读取整个文件。 (一般来说,部分校验和不足以检测更改。)某些校验和算法也相对昂贵。
您还需要知道文件的先前校验和是什么。这意味着您需要一种方式/地方来存储它。这可能只是另一个文件,但作为同步过程的一部分,您需要一些基础设施来(可靠地)更新该文件。
对多个校验和进行异或操作会导致您不知道哪些文件已更改的问题。如果一个文件发生更改,您需要同步所有文件。
理论上,文件更改且 MD5 校验和相同是可能的:2^128 中的概率为 1。您可能可以忽略这一点......除非您的应用程序是安全关键型应用程序。 (请注意,MD5 冲突攻击在某些情况下是实用的;请参阅 https://en.wikipedia.org/wiki/Collision_attack)
另一件事是我怀疑您正在尝试解决已解决的问题。例如,Linux/Unix rsync
实用程序可以选择使用时间戳或 (MD5) 校验和来决定哪些文件需要同步。
您不需要自己实现所有内容(用 Java)。
针对您的“我们无法访问旧文件树”,有一个简单的解决方案。每次重新启动时:
- 复制文件树
- 将当前文件与您上次重新启动时创建的副本进行比较。
就像我在评论中所说的,发挥你的想象力。
关于java - 从摘要或校验和中检测目录(java 8)中已更改的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58739925/