此迭代器改编自高阶Perl中的dir_walk。
sub dir_walk
{ my @queue = shift; # push first directory onto FIFO queue
return sub # this is the iterator
{ if (@queue)
{ my $entry = shift @queue; # take the first item off the queue
# Here if $entry is a Directory
if (-d $entry && opendir my $dh, $entry)
{ # read all the files in the directory into an array
my @newfiles = grep {$_ ne "." && $_ ne ".."} readdir $dh;
# prepend the path to the file names
push @queue, map "$entry/$_", @newfiles;
}
return $entry;
}
else {return;} # ignore files here, they're in the queue
};
}
它似乎是作弊,因为它违反了迭代器的一个主要目的,避免加载大型数组,通过在例程中隐藏大数组@newfiles和@queue。 (好的,文件只有最大的子目录一样大,但仍然......)
有没有办法可以重写它,所以它可以更像
while (<FH>){ }
用于读取文件,避免使用不必要的大数组?
我能想到的只是将DOS目录命令保存到文件中,然后一行读取文件,如上所述。这需要更多的解析,而且我所知道的还有隐藏大文件的地方。
答案 0 :(得分:0)
一种相当明显的方法(但需要更多代码的方法)是不是一次读取整个目录而是将所有名称都放在队列中,将readdir
包装在另一个迭代器中并放入队列中的迭代器。然后在使用队列时,检查前面的元素是否是一个迭代器,如果是这样,从中挑选项目直到它耗尽,而不是简单地移开元素。