2010-03-02 8 views

Respuesta

9

Sí, hay una mejor manera. En Windows puede usar la interfaz FileSystemWatcher, en Linux, use inotify.

de 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 y http://search.cpan.org/perldoc?Sys::Gamin puede funcionar en sistemas de archivos y UNIXes donde inotify no lo hace. – ephemient

2

File::Tail sondeará el archivo, pero tiene algunas ventajas sobre el enfoque:

  • se vuelve a calcular el tiempo de sondeo dinámicamente basado en el número de líneas escritas desde la última encuesta
  • Si el archivo permanece sin cambios, el sondeo se ralentizará para evitar el uso de la CPU
  • File :: Tail detectará si el archivo ha sido truncado, movido y/o recreado y silenciosamente abra el archivo para usted
  • Puede atar un controlador de archivo regular que puede usar como lo normal sin ninguna API o sintaxis especial.

Ejemplo de la perldoc:

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