2016-09-28 5 views
0

ディレクトリにファイルの存在を確認する簡単なプログラムを書いています。このファイルは、一定の時間を持たない外部プログラムによって作成されます。だから、私はそれが生まれたら直ちに処理する必要があるので、ループ内のファイルの存在を確認する必要があります。Perl:ファイルが存在するまでディレクトリを読み取る

このプログラムは、ファイルが作成されていても連続して実行されます。

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


my $dir = "/my/path"; 
opendir(my $dh, $dir) || die "can't opendir $dir: $!"; 
my @files = grep { /^[^\.]/ && -f "$dir/$_" } readdir($dh); 
until (@files) { 
    print "No files Found: Sleeping for a sec\n"; 
    sleep(1); 
    @files = grep { /^[^\.]/ && -f "$dir/$_" } readdir($dh); 
} 
print @files; 

次のプログラムは期待どおりに機能しました。

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


my $dir = "/my/path"; 
opendir(my $dh, $dir) || die "can't opendir $dir: $!"; 
my @files = grep { /^[^\.]/ && -f "$dir/$_" } readdir($dh); 
closedir $dh; 
until (@files) { 
    opendir(my $dh, $dir) || die "can't opendir $dir: $!"; 
    print "No files Found: Sleeping for a sec\n"; 
    sleep(1); 
    @files = grep { /^[^\.]/ && -f "$dir/$_" } readdir($dh); 
    closedir $dh; 
} 

print @files; 

これらの2つのアプローチの違いを知りたいと思います。なぜ私はループ内で毎回ディレクトリを読んでいても、以前のものは動作しませんでした。なぜ私はそれを動作させるためにループ内で毎回ディレクトリを開く必要がありますか?

+0

に短縮することができますします。 – AbhiNickz

+1

[Filesys :: Notify :: Simple](https://metacpan.org/pod/Filesys::Notify:Simple)を見てください。 – nwellnhof

答えて

6

readdirの後に、ディレクトリハンドルがファイルリストの最後に達したため、次回にファイルが追加されたとしても、それ以上読み取る必要はありません。これは、ハンドルがリストコンテキストで使用されたときの最初の読み取りで発生します。

rewinddirへの呼び出しをループに追加すると、ディレクトリハンドルが次のreaddirのディレクトリの先頭に戻ります。

または、globを使用してuntil条件

my $cond = qr(^[^\.]); 

until (grep { $cond && -f } glob "$dir/*") { 
    say "no files"; 
    sleep 1; 
} 

ディレクトリは、すべてのテストのために再読み込みされ、この方法は、テストを右に置きます。 globはパスを返すので、これは事を単純化します。

最初のプログラムであなたは一度、あなたはそれがファイルに関する&第二プログラムで最新の情報が含まれていないように、古い$のDHからファイルを読み込むしようとしているのopendir使用しているのでそれはまた

my @files; 

sleep 1 until @files = grep { $cond && -f } glob "$dir/*"; 

say for @files; 
+0

@ arunesh-singhなぜこのようなことが起こるのか、別のコードスニペットに関するコメントで答えを更新しました。 – zdim

関連する問題