1

https://metacpan.org/pod/Mac::FSEventsを使用してchange-eventが呼び出されるたびに、どのファイルが変更されたかを確認することはでき ますか?

どうもありがとう!:)

4

1 に答える 1

7

ファイルシステムイベントAPIは、ファイルの変更の大きなツリーをミラーリングするように設計されています。特定のファイルの変更をミラーリングする場合は、IO::KQueueを使用した方がよい場合があります。perlバインディングには、イベントフラグの定数がいくつかありませんが、これらはファイルシステムイベントプログラミングガイドから入手できます。

このスクリプトを使用すると、次のファイルイベントが出力されます。'/path'

#!/usr/bin/perl
use strict;
use warnings;

use IO::Select    qw[];
use Mac::FSEvents qw[FILE_EVENTS];

my $fse = Mac::FSEvents->new({
    path  => '/path',
    flags => FILE_EVENTS
});

my $select = IO::Select->new($fse->watch);

# http://developer.apple.com/library/mac/#documentation/Darwin/Reference/FSEvents_Ref/FSEvents_h/index.html#//apple_ref/c/tag/FSEventStreamEventFlags
my %names = reverse (
    kFSEventStreamEventFlagNone              => 0x00000000,
    kFSEventStreamEventFlagMustScanSubDirs   => 0x00000001,
    kFSEventStreamEventFlagUserDropped       => 0x00000002,
    kFSEventStreamEventFlagKernelDropped     => 0x00000004,
    kFSEventStreamEventFlagEventIdsWrapped   => 0x00000008,
    kFSEventStreamEventFlagHistoryDone       => 0x00000010,
    kFSEventStreamEventFlagRootChanged       => 0x00000020,
    kFSEventStreamEventFlagMount             => 0x00000040,
    kFSEventStreamEventFlagUnmount           => 0x00000080,
    kFSEventStreamEventFlagItemCreated       => 0x00000100,
    kFSEventStreamEventFlagItemRemoved       => 0x00000200,
    kFSEventStreamEventFlagItemInodeMetaMod  => 0x00000400,
    kFSEventStreamEventFlagItemRenamed       => 0x00000800,
    kFSEventStreamEventFlagItemModified      => 0x00001000,
    kFSEventStreamEventFlagItemFinderInfoMod => 0x00002000,
    kFSEventStreamEventFlagItemChangeOwner   => 0x00004000,
    kFSEventStreamEventFlagItemXattrMod      => 0x00008000,
    kFSEventStreamEventFlagItemIsFile        => 0x00010000,
    kFSEventStreamEventFlagItemIsDir         => 0x00020000,
    kFSEventStreamEventFlagItemIsSymlink     => 0x00040000
);

use constant kFSEventStreamEventFlagItemIsFile => 0x00010000;

while ($select->can_read) {
    for my $event ($fse->read_events) {
        my $flags = $event->flags;
        my @names;

        next unless $flags & kFSEventStreamEventFlagItemIsFile;

        while ((my $flag = $flags & -$flags) != 0) {
            push @names, $names{$flag} || sprintf '0x%.8X';
            $flags &= ~$flag;
        }

        printf qq['%s': %s\n], $event->path, join ' | ', @names;
    }
}
$fse->stop;

イベントの例:

$ echo foo > foo.txt
'/path/foo.txt': kFSEventStreamEventFlagItemCreated | kFSEventStreamEventFlagItemModified | kFSEventStreamEventFlagItemIsFile

$ touch foo.txt
'/path/foo.txt': kFSEventStreamEventFlagItemInodeMetaMod | kFSEventStreamEventFlagItemIsFile

$ echo foo >> foo.txt
'/path/foo.txt': kFSEventStreamEventFlagItemModified | kFSEventStreamEventFlagItemIsFile

$ mv foo.txt bar.txt
'/path/foo.txt': kFSEventStreamEventFlagItemRenamed | kFSEventStreamEventFlagItemIsFile
'/path/bar.txt': kFSEventStreamEventFlagItemRenamed | kFSEventStreamEventFlagItemIsFile

$ rm bar.txt
'/path/bar.txt': kFSEventStreamEventFlagItemRemoved | kFSEventStreamEventFlagItemIsFile
于 2012-06-21T00:51:19.797 に答える