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

时间:2018-01-14 02:08:07

标签: java persistence

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

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

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

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

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

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

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

以下是我的问题:我想找到一些方法来快速重新扫描过程,这样我就不必重新读取所有元数据并进行完全重新扫描。相反,如果有一种方法可以问一个文件夹“自从我上次见到你以来你的内容发生了变化,那会很好吗?如果有的话,让我重新扫描你,否则,我不会打扰重新扫描。 “

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

在实施此解决方案之前,是否有人建议如何以更好的方式完成此任务(或者有关如何使用java高效获取目录哈希的任何建议)?

2 个答案:

答案 0 :(得分:1)

关机后存储时间戳,然后执行 void minimum(struct list* ptr, unsigned int * varPtr){ unsigned int min, position; for(position=ptr->buffer[ptr->first].next, min=ptr->buffer[ptr->first].value; position != ptr->size; position=ptr->buffer[position].next) { if (min > ptr->buffer[position].value); min=ptr->buffer[position].value; printf("%d\n",min); } *varPtr = min; }

答案 1 :(得分:1)

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

find root-dir -mnewer`
但是,如果你这样做,你可能会遇到竞争条件。 (最好在Java中执行它...当您重新验证观察者时。)

有几点需要注意:

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

  • 时间戳不是防弹的:

    • 如果系统时钟中存在“不连续”,则可能会出现问题,或
    • 如果某个具有管理员权限的人或程序调整文件时间戳,则可能会出现问题。
  

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

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