在perl中,如何编写一个在幕后没有大文件的迭代器?

时间:2016-01-12 22:08:23

标签: perl iterator

此迭代器改编自高阶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目录命令保存到文件中,然后一行读取文件,如上所述。这需要更多的解析,而且我所知道的还有隐藏大文件的地方。

1 个答案:

答案 0 :(得分:0)

一种相当明显的方法(但需要更多代码的方法)是不是一次读取整个目录而是将所有名称都放在队列中,将readdir包装在另一个迭代器中并放入队列中的迭代器。然后在使用队列时,检查前面的元素是否是一个迭代器,如果是这样,从中挑选项目直到它耗尽,而不是简单地移开元素。