Reputation: 2876
I would like to watch a set of files for changes, and do so without a large CPU and battery penalty. Ideally, my perl code would run on both macos and linux, but the former is more important. I tried
I tried Mac::FSEvents
, which works on macos and seems to do nicely for directories, but not for files as far as I can tell.
my $fs = Mac::FSEvents->new('try.txt');
my $fh= $fs->watch;
my $sel = IO::Select->new($fh);
while ( $sel->can_read ) {
my @events = $fs->read_events;
for my $event ( @events ) {
printf "File %s changed\n", $event->path;
}
}
which simply does not respond; and the promisingly more OS agnostic
use File::Monitor;
my $monitor = File::Monitor->new();
my @files= qw(try.txt);
foreach (@files) { $monitor->watch($_); }
which consumes 100% CPU. the $monitor-watch()
alone does not block. I also tried
use File::Monitor;
my $monitor = File::Monitor->new();
$monitor->watch('try.txt', sub {
my ($name, $event, $change) = @_;
print "file has changed\n";
});
but this immediately returns.
I found another,
use File::ChangeNotify;
my $watcher =
File::ChangeNotify->instantiate_watcher
( directories => [ './' ],
filter => qr/try\.txt/,
);
# blocking
while ( my @events = $watcher->wait_for_events() ) {
print "file has changed\n";
}
but the CPU utilization is again high (70%).
Maybe these are all the wrong cpan modules, too. could someone please give me advice on how I should do this?
regards,
/iaw
Upvotes: 0
Views: 380
Reputation: 2876
Partial (macos-specific) example:
use IO::Select;
use Mac::FSEvents;
my $fs = Mac::FSEvents->new(
path => ['./try.txt', './try2.txt'],
file_events => 1,
);
my $fh= $fs->watch;
my $sel = IO::Select->new($fh);
while ( $sel->can_read ) {
my @events = $fs->read_events;
for my $event ( @events ) {
printf "File %s changed\n", $event->path;
}
}
(i.e., it needed the file_events flag.)
Upvotes: 1