看起来您想要监视一个目录的变化。这是一项复杂的工作,但有很好的模块可以使用。最简单推荐的一个可能是
Linux::Inotify2。
该模块实现了与 Linux 2.6.13 及更高版本的 Inotify 文件/目录变更通知系统的接口。
看起来这就是你需要的东西。
任何这样的监视都需要额外的事件处理。本示例使用
AnyEvent。
use warnings;
use strict;
use feature 'say';
use AnyEvent;
use Linux::Inotify2;
my $dir = 'dir_to_watch';
my $inotify = Linux::Inotify2->new or die "Can't create inotify object: $!";
$inotify->watch( $dir, IN_MODIFY | IN_CREATE, sub {
my $e = shift;
my $name = $e->fullname;
say "$name modified" if $e->IN_MODIFY;
say "$name created" if $e->IN_CREATE;
});
my $inotify_w = AnyEvent->io (
fh => $inotify->fileno, poll => 'r', cb => sub { $inotify->poll }
);
1 while $inotify->poll;
如果您只关心
新文件,那么只需要一个常量以上。对于这两种类型的事件,
$name
都有新文件的名称。据我所在系统上
man inotify
的介绍,返回的
inotify_event
结构中的
name
字段标识了目录内的文件名。适当表示
inotify_event
结构的对象是
Linux::Inotify2::Watcher
。
使用
IN_CREATE
似乎是您的目的的明显解决方案。我测试了在同一命令行上创建两个文件,并使用分号分隔的两个重定向
echo
命令,以及通过
touch
创建文件。写入的文件被检测为单独的事件,
touch
的文件也是如此。
使用
IN_MODIFY
也可能奏效,因为它监视了(在
$dir
中)所观察对象(始终为目录)中的任何文件系统对象,例如文件、目录、符号链接、设备节点等等。
对于测试来说,上述由
echo
编写的两个文件报告为单独的事件。但是
touch
的文件并没有报告,因为数据没有更改(文件没有被写入)。
哪种方法更适合您的需求取决于细节。例如,工具可能在启动时打开日志文件,但只有在以后才写入它。上述两种方法在这种情况下的行为将有所不同。所有这些都应该在特定条件下仔细研究。
我们可能会考虑竞争条件,因为当代码执行时,其他文件可能会溜进来。但是该模块要好得多,并且在处理程序完成后它确实会报告新更改。我通过在代码运行(和休眠)时创建文件来测试,并且它们被报告了。
一些其他值得注意的事件驱动编程框架包括
POE和
IO::Async。
File::Monitor也可以完成此类工作。