当文件发生变化时,为什么Perl的Win32 :: ChangeNotify会触发两个事件?

时间:2014-05-21 07:37:51

标签: windows perl winapi

我想在更改源代码或测试时自动运行prove,我正在使用Win32::ChangeNotify,但我不知道为什么即使单个文件发生更改,while body运行了两次,我实际上想要监视所有更改,但只执行一次动作。

require Win32::ChangeNotify;

$notify = Win32::ChangeNotify->new("./", 1, "LAST_WRITE");

while (my @events = $notify->wait) {
    print @events, "----\n";
    $notify->reset;
}

2 个答案:

答案 0 :(得分:3)

Raymond Chen在Why does saving a file in Notepad fire multiple FindFirstChangeNotification events?

中讨论了类似的主题
  

记住Read­Directory­ChangesW function的原始设计目标:它是让应用程序缓存目录列表并以增量方式更新它。鉴于这些设计目标,除了减少聊天的性能优势之外,不需要在内核中过滤掉冗余通知。理论上,ReadDirectoryChangesW可以每5秒报告一次虚假变化,该函数的目标受众仍然可以正常运行(虽然次优)。

     

鉴于此预期使用模式,Read­Directory­ChangesW的任何消费者都需要接受您收到的任何通知都包含您所需的最少信息,以使您的缓存目录信息保持最新,但它可以包含额外信息,太。 如果您只想响应实际更改,则需要将新文件属性与旧文件属性进行比较。强调我的

并且,他在下面进一步澄清:

  

文件系统更改通知不会检查写入是否等于先前的数据。 (这对于大型文件写入来说非常昂贵。)记住更改通知的目的。 虚假通知是合法的。 -Raymond(再次,强调我的

答案 1 :(得分:1)

File::ChangeNotify提供了更好的活动和它的跨平台。

use File::ChangeNotify;
use Data::Dumper;

$| = 1;

my $watcher = File::ChangeNotify->instantiate_watcher(
    directories => [ 't', 'lib' ],
    filter => qr/\.t|\.pl|\.pm/,
);

while (my @events = $watcher->wait_for_events) {
    print Dumper(@events);
}

在修改单个文件时打印单个事件,至少是我观察到的内容。