如何在程序终止和重新启动后有效地检查目录树的变化?

How to check tree of directories for changes efficiently after termination and restart of program?

我正在编写一个从磁盘加载数据库的程序。它递归扫描用户指定的每个文件夹,从每个文件中读取必要的元数据,然后将其保存在程序库中,成为适合用户显示和操作的数据结构。

对于合理大小的数据集,此过程需要 5-10 分钟。在高端,我可以想象它需要半个小时。

它还为树中的每个目录设置了一个 watcher,因此如果在程序处于 运行 的初始扫描后发生任何更改,则可以重新创建更改的文件或文件夹扫描并使用新数据更新库。

当程序终止时,库数据结构被序列化到磁盘,然后在下一个会话开始时重新加载。

这留下了一个需要解决的漏洞 -- 如果文件在会话之间发生更改,则无法了解这些更改。

目前实现的解决方案是,在启动程序加载持久化数据时,重新扫描整个文件结构,并将扫描到的信息与加载的数据进行比较,如果有不同,则进行替换。

鉴于重新扫描读取每个文件的元数据并重新加载所有内容,只是在确认没有任何更改后丢弃它,这对我来说似乎是一种非常低效的方法。

这是我的问题:我想找到一些方法来简化这个重新扫描过程,这样我就不必重新读取所有元数据并进行全面重新扫描。相反,如果有办法询问文件夹 "have your contents changed at all since the last time I saw you? If so, let me rescan you, otherwise, I won't bother rescanning."

就好了

我想到的一个想法是获取文件夹内容的校验和并将其存储在数据库中,然后在重新扫描期间比较哈希值。

在我实施这个解决方案之前,有没有人对如何以更好的方式完成这个有任何建议(或者任何关于如何有效地使用 java 获取目录哈希的建议)?

关闭时存储时间戳,然后只需执行 find -mnewer?

最实用的方法是遍历文件树,检查时间戳比应用程序停止时更新的文件。例如

find root-dir -mnewer`

不过,如果您那样做,您可能 运行 进入竞争条件。 (最好在 Java 中执行此操作 ... 当您重新实例化观察者时。)

有几点注意事项:

  • 扫描文件树需要时间。树越大,需要的时间越长。如果您正在谈论数百万个文件,可能需要几个小时,只是查看时间戳。

  • 时间戳不是防弹的:

    • 如果系统时钟 "discontinuities" 或
    • 可能会出现问题
    • 如果某些具有管理员权限的人或程序调整文件时间戳,可能会出现问题。

One idea that occurs to me is to take a checksum of the folder's contents and store that in the database, and then compare the hashes during the re-scan.

计算文件的校验和或哈希值需要更长的时间。唯一可行的方法是操作系统本身 自动 计算并记录文件校验和或每次更新文件时的哈希值。 (这将对所有文件/目录写入操作产生重大性能影响......)