2014-03-01 111 views
0

我打算遞歸遍歷包含這段perl腳本的目錄。 這個想法是遍歷其父目錄包含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); 
+7

爲什麼要重新發明輪子?使用['File :: Find']](http://search.cpan.org/perldoc?File%3A%3AFind)。 – TLP

+0

我不應該使用圖書館。 – user3368737

+1

@ user3368737:即使是核心模塊?然後使用源碼Luke:'perldoc -m File :: Find' – toolic

回答

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) { ... }

+0

謝謝你非常。這不是作業,只是一個腳本,可以幫助我解決一些數據。我是perl的新手,還有很長的一段路要走。 – user3368737