2016-09-28 96 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; 

我想知道这两种方法的区别。为什么前一个没有工作,即使我每次都在循环读取目录。为什么我需要在循环中每次打开目录才能使其工作?

+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返回的路径,这简化了事情。

它也因为在第一个程序,您使用的执行opendir一次,然后你想因此它不包含有关文件及在第二程序的最新信息,来读取旧的$ DH文件缩短到

my @files; 

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

say for @files; 
+0

@ arunesh-singh我更新了答案,评论了为什么会发生这种情况,以及另一个代码片段。 – zdim