在上一个问题中,我的一个问题是我的应用程序如何知道文件已被重写。我应该添加:“由另一个应用程序”。首先,我尝试了 ShellNotify,它报告目录中的更改,而不是特定文件中的更改 afaik,我错过了什么吗?
现在我在计时器中使用 FileAge,它每秒检查特定文件是否已更改。虽然这有效,但它会检测到两次修改,相隔约 13 毫秒;当我将测试间隔更改为 10 秒时,此行为仍然存在。下面的代码是定时器的回调。
procedure TAMI_Column_Selector.doWork (Sender: TObject);
var new_stamp: TDateTime;
begin
if FileAge (remove_extension (FileName) + '.csv', new_stamp) then
begin
if (new_stamp <> FDateTimeStamp) then
begin
FDateTimeStamp := new_stamp;
FTask.SyncCall (notify_user);
end; // if
end; // if
end; // doWork //
我的问题:
- 究竟是什么导致在
notify_user
上面的代码中被调用两次?文件系统的愚蠢错误或一些奇怪的行为(例如,修改日期设置在打开和关闭文件时)? - 每秒检查文件是否已更改感觉有点“浪费”。有没有像 ShellNotify 这样的东西,它只在特定文件被修改时通知我?
更新
David Heffeman 的答案(使用ReadDirectoryChangesW
而不是轮询)是问题 2 的正确答案。但是,如问题 1 中所述,它也会在一次修改期间(从用户的角度)导致多次调用。
我比较ReadDirectoryChangesW
了和轮询方法。测试了两个文件(0.5MB 和 10MB)。在这两种情况下,轮询方法都被调用了两次,并且ReadDirectoryChangesW
被调用了多次(3 到 5 次)。我将恢复轮询方法并忽略第一个FileAge
更改。我知道我无法确定这种行为是否一致,因为我不了解导致它的机制。