2010-03-02 16 views
5

Tôi đã tự hỏi nếu có một cách để chờ đợi cho một tập tin được cập nhật, và sau đó đọc từ nó một khi nó được cập nhật. Vì vậy, nếu tôi có file.txt, tôi muốn đợi cho đến khi một cái gì đó mới được ghi vào nó, và sau đó đọc nó/xử lý nó/etc. Hiện tại tôi đang bỏ phiếu bằng cách sử dụng Time::HiRes::sleep(.01), nhưng tôi tự hỏi nếu có cách nào tốt hơn. Cảm ơn.Cách tốt nhất để đợi cho đến khi tệp được cập nhật và sau đó đọc từ tệp đó trong Perl?

Trả lời

9

Có cách nào tốt hơn. Trên cửa sổ, bạn có thể sử dụng giao diện FileSystemWatcher, trên Linux, sử dụng inotify.

của 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 và http://search.cpan.org/perldoc?Sys::Gamin có thể làm việc trên các hệ thống tập tin và UNIX nơi inotify không. – ephemient

2

File::Tail sẽ thăm dò ý kiến ​​các tập tin, nhưng có một vài ưu điểm so với cách tiếp cận của bạn:

  • Thời gian thăm dò được tính toán lại tự động dựa trên số của dòng được viết kể từ cuộc thăm dò cuối cùng
  • Nếu tệp không thay đổi, việc bỏ phiếu sẽ chậm để tránh sử dụng hết CPU
  • Tệp :: Tail sẽ phát hiện xem tệp đã bị cắt ngắn, di chuyển và/hoặc tạo lại hay không mở tệp cho bạn
  • Nó có thể gắn một tay cầm tệp thông thường mà bạn có thể sử dụng như bình thường mà không có bất kỳ API hoặc cú pháp đặc biệt nào.

Ví dụ từ perldoc:

use File::Tail; 
my $ref=tie *FH,"File::Tail",(name=>$name); 
while (<FH>) { 
    print "$_"; 
} 
Các vấn đề liên quan