perl中的递归目录遍历

时间:2014-03-01 17:12:19

标签: perl file recursion traversal

我打算以递归方式遍历包含这段perl脚本的目录。 我们的想法是遍历其父目录包含perl脚本的所有目录,并将所有文件路径列为单个数组变量。然后返回列表。

出现错误消息:

readdir() attempted on invalid dirhandle $DIR at xxx 
closedir() attempted on invalid dirhandle $DIR at xxx

附上代码供参考,提前谢谢。

use strict;
use warnings;
use Cwd;
our @childfile = ();
sub recursive_dir{

    my $current_dir = $_[0]; # a parameter

    opendir(my $DIR,$current_dir) or die "Fail to open current directory,error: $!";
    while(my $contents = readdir($DIR)){
        next if ($contents =~ m/^\./); # filter out "." and ".."
        #if-else clause separate dirs from files 
        if(-d "$contents"){
            #print getcwd;
            #print $contents;
            #closedir($DIR);
            recursive_dir(getcwd."/$contents");
            print getcwd."/$contents";
        }
        else{
            if($contents =~ /(?<!\.pl)$/){
                push(@childfile,$contents);
            }
        }
    }
    closedir($DIR);
    #print @childfile;
    return @childfile;
}

recursive_dir(getcwd);

1 个答案:

答案 0 :(得分:0)

请告诉我们这是否是作业?欢迎您向作业寻求帮助,但它会改变您应给予的答案。

您依靠getcwd为您提供当前正在处理的目录,但您永远不会更改当前工作目录,因此您的程序将无限循环并最终耗尽内存。您只需使用$current_dir代替。

我不相信您显示的程序可以生成这些错误消息。您的代码会检查opendir是否已成功并且程序将死亡,除非$DIR有效,因此后续readdirclosedir 必须使用有效处理

其他一些观点:

  • # a parameter这样的评论很荒谬,只会让您的代码变得混乱

  • 大写字母通常保留用于包名称等全局标识符。并且$dir是目录句柄的可怜名称,因为它也可能表示目录名称或目录路径。使用$dir_handle$dh

  • 使用负面后卫来检查文件名是否以.pl结尾是很疯狂的。只需使用push @childfile, $contents unless $contents =~ /\.pl$/

  • 即可
  • 您永远不会使用子程序中的返回值,因此从每次调用返回可能是巨大数组的内存都是浪费。 @childfile可在整个计划中访问,因此您可以直接从任何地方访问

  • 不要将标量变量放在双引号内。它只是将值强制为字符串,这可能是不必要的,并可能导致奥术错误。仅使用-d $contents

  • 您可能希望忽略符号链接,否则您可能无休止地循环。您应该将else { ... }更改为elsif (-f $contents) { ... }