检测文件是否已更改的强大方法

时间:2016-06-29 18:37:35

标签: c++ linux windows macos posix

认为这个问题还没有得到我的用例的回答。

我们希望检测用户是否更改了文件而没有重新读取其内容,以便根据文件内容缓存计算结果。我们的程序是一个长期运行的程序,它允许用户单击按钮来执行基于程序中输入的数据和存储在外部文件中的数据的计算(抱歉,我不能比这更具体)。需要读取,处理外部数据并根据需要构建各种数据结构,因此我们尝试在计算之间缓存这些数据,以便在用户更改程序本身的数据时加快重新计算,而不是数据在外部文件中。但是,如果外部文件已更改,我们必须重新阅读。

对于每个外部资源,我们都要检查修改时间和文件大小是否已经改变,但实际上并不是那么强大,如果他们有例如fileA和fileB具有相同的大小和时间戳以及copy或fileA到fileC,使用fileC作为外部资源,然后将fileB复制到fileC。系统保留原始文件的修改时间,大小相同,因此我们不会重新读取外部资源。

我们的程序在Windows,macOS和Linux上运行,是用C ++编写的,我们完全可以使用特定于平台的代码来检测文件更改。我们对检测由文件路径标识的文件的内容是否已更改而不实际读取文件本身的最强大的方法感兴趣。

1 个答案:

答案 0 :(得分:2)

我已将此答案作为社区维基,因此其他人可以为问题中列出的各种平台添加他们的想法。

的Linux

的MacOS

选项1

设置包含该文件的watches the directory的线程。当目录发生变化时,您必须检查您关心的文件是否实际发生了变化。这可能意味着打开并重新读取文件(例如,计算当前校验和)。但由于您必须在更改通知后才能执行此操作,因此可以接受此开销。

我相信(但尚未验证)如果有人在现有文件上复制相同大小的同一时间戳文件,您将收到目录更改通知。

选项2

使用opportunistic lock打开文件。这涉及通过调用DeviceIoControl创建锁定,然后发出对GetOverlappedResult的阻止调用,当另一个进程尝试更改文件时,该调用将解锁。您的程序可以释放锁定,允许其他进程更新文件,并知道文件正在更改。