🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.perl
Article #52099

Przeglądanie drzewa katalogów w poszukiwaniu pliku

#52099
From: Jarosław Lubczyński
Date: Tue, 07 Dec 2010 14:42
82 lines
3611 bytes
Witam ponownie :)

Problem wygląda tak:
Mam następujące (przykładowe) drzewo katalogów (start od pewnego 
katalogu bieżącego, dowolny (no, prawie :) ) rozmiar struktury:

my @DirTree = qw
{
     A
     A/B1
     A/B1/C1
     A/B1/C2
     A/B2
     A/B2/C1
     A/B2/C1/D1
     A/B2/C1/D2
};

W dowolnym katalogu z listy może pojawić się od czasu do czasu plik o 
znanej nazwie, powiedzmy:

Readonly my $FileName => 'findme.txt';

Zadanie mam takie: po pojawieniu się pliku możliwie jak najszybciej 
wykonać na nim określoną operację, plik usunąć i czekać na kolejne 
pojawienie się pliku o takiej samej nazwie - być może w innym miejscu 
struktury katalogów.

Rozwiązanie jest niby proste (sprawdzanie co 5 sekund, opóźnienie do 
przyjęcia):

while( 1)
{
     foreach my $Path ( @DirTree)
     {
         fileAction( $Path) if( -f "$Path/$FileName");
     }
     sleep( 5);
}

sub fileAction
{
     my( $Path) = @_;
     my $FilePath = "$Path/$FileName";
     # do sth on $Path and/or $FilePath ....
     unlink $FilePath;
}

Taki też mniej więcej kod zmajstrowałem. Działa bez zarzutu. Niestety 
top melduje, że mój program zajmuje niepotrzebnie czas procesora - jeden 
z trzech na liście od góry, co prawda tylko na poziomie 0.5..1% użycia 
CPU na moim laptopie (CentOS 5.4 pod VMWare na WinXP SP2 z P4/2.4GHz, 
Perl 5.8.8) ale to wystarczy by użytkownik trochę marudził.

W zasadzie maruda ma rację - pliki o wskazanej nazwie mogą pojawiać się 
stosunkowo rzadko (powiedzmy, że raz na tydzień) więc zastosowany 
algorytm pollingowy zupełnie niepotrzebnie (chociaż w niewielkim 
stopniu) bezustannie obciąża system.

No i teraz pytanie zasadnicze: czy istnieje mechanizm (lub gotowy pakiet 
CPAN), który wygeneruje mi zdarzenie na wyżej opisaną okoliczność?

Spróbowałem POE::Component::DirWatch ale wygląda, że pakiet ten też 
stosuje polling niestety. Przykładowy kod z ww pakietu obserwujący tylko 
jeden katalog obciąża mi system w podobnym stopniu jak powyższy kawałek 
programu. Doinstalowałem IO::AIO - wygląda, że bez zmian, ale nie wiem 
czy DirWatch go wykorzystuje (powinien automagicznie).

Wersję z File::Find też napisałem, z podobnym skutkiem.

Jakie mam inne opcje? Mam niejasne wrażenie, że zdarzenie o pojawieniu 
się pliku powinnno wstępnie przyjść od kernela. Czy Linux daje takie 
wsparcie? A Perl je obsługuje? Kernel 2.6.18, Perl 5.8.8 jak wspomniałem.

-- 
Pozdrawiam
Jarek Lubczyński
(eljot<NULL>90125 at gmail dot com)
Nawiasy trójkątne z zawartością zbędne są

There are 10 kinds of people:
Those who understand binary and those who don't
Technical Details
Message-ID: <idlh5u$k3f$1@opal.futuro.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!newsfeed.pionier.net.pl!news.internetia.pl!opal.futuro.pl!not-for-mail

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!newsfeed.pionier.net.pl!news.internetia.pl!opal.futuro.pl!not-for-mail
From: Jarosław Lubczyński <guess@who.com.pl>
Newsgroups: pl.comp.lang.perl
Subject: Przeglądanie drzewa katalogów w
 poszukiwaniu pliku
Date: Tue, 07 Dec 2010 15:42:59 +0100
Organization: Pro Futuro
Lines: 83
Message-ID: <idlh5u$k3f$1@opal.futuro.pl>
Reply-To: guess@who.com.pl
NNTP-Posting-Host: ns.elkomtech.com.pl
Mime-Version: 1.0
X-Trace: opal.futuro.pl 1291732991 20591 62.233.147.142 (7 Dec 2010 14:43:11 GMT)
X-Complaints-To: usenet@futuro.pl
NNTP-Posting-Date: Tue, 7 Dec 2010 14:43:11 +0000 (UTC)
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.2.12) Gecko/20101027 Thunderbird/3.1.6
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit