2010-03-02 64 views
5

我想知道是否有辦法等待文件被更新,然後一旦更新就從中讀取。所以如果我有file.txt,我想等到有新的東西寫入它,然後讀取它/處理它/ etc。目前我輪詢使用Time::HiRes::sleep(.01),但我想知道是否有更好的方法。謝謝。什麼是等待文件更新並在Perl中讀取的好方法?

回答

9

是的,還有更好的方法。在Windows上,您可以使用FileSystemWatcher界面,在Linux上使用inotify

的Windows

use Win32::FileSystem::Watcher; 

my $watcher = Win32::FileSystem::Watcher->new("c:\\"); 

# or 

my $watcher = Win32::FileSystem::Watcher->new(
    "c:\\", 
    notify_filter => FILE_NOTIFY_ALL, 
    watch_sub_tree => 1, 
); 

$watcher->start(); 
print "Monitoring started."; 

sleep(5); 

# Get a list of changes since start(). 
my @entries = $watcher->get_results(); 

# Get a list of changes since the last get_results() 
@entries = $watcher->get_results(); 

# ... repeat as needed ... 

$watcher->stop(); # or undef $watcher 

foreach my $entry (@entries) { 
    print $entry->action_name . " " . $entry->file_name . "\n"; 
} 

# Restart monitoring 

# $watcher->start(); 
# ... 
# $watcher->stop(); 

LINUX

use Linux::Inotify2; 
my $inotify = new Linux::Inotify2(); 

foreach (@ARGV) 
{ 
    $inotify->watch($_, IN_ALL_EVENTS); 
} 

while (1) 
{ 
    # By default this will block until something is read 
    my @events = $inotify->read(); 
    if (scalar(@events)==0) 
    { 
    print "read error: $!"; 
    last; 
    } 

    foreach (@events) 
    { 
    printf "File: %s; Mask: %d\n", $_->fullname, $_->mask; 
    } 
} 
+2

http://search.cpan.org/perldoc?SGI::FAM和http://search.cpan.org/perldoc?Sys::Gamin可能適用於文件系統和unotify不支持的UNIX。 – ephemient 2010-03-02 22:50:22

2

File::Tail將輪詢文件,但在你的方法有幾個優點:

  • 投票表決時間重新計算動態地基於數字自上次輪詢後寫入的行數
  • 如果文件保持不變,輪詢將會減慢以避免使用CPU
  • File :: Tail將檢測文件是否被截斷,移動和/或重新創建,爲你打開文件
  • 它可以綁定一個普通的文件句柄,你可以像普通文件一樣使用,不需要任何特殊的API或語法。從的perldoc

實施例:

use File::Tail; 
my $ref=tie *FH,"File::Tail",(name=>$name); 
while (<FH>) { 
    print "$_"; 
} 
相關問題