我认为这是一个简单的问题,但我坚持了下来一段时间了! 我需要一双崭新的眼睛这一点。
事情是我有这样的代码在Perl:
#!c:/Perl/bin/perl
use CGI qw/param/;
use URI::Escape;
print "Content-type: text/html\n\n";
my $directory = param ('directory');
$directory = uri_unescape ($directory);
my @contents;
readDir($directory);
foreach (@contents) {
print "$_\n";
}
#------------------------------------------------------------------------
sub readDir(){
my $dir = shift;
opendir(DIR, $dir) or die $!;
while (my $file = readdir(DIR)) {
next if ($file =~ m/^\./);
if(-d $dir.$file)
{
#print $dir.$file. " ----- DIR\n";
readDir($dir.$file);
}
push @contents, ($dir . $file);
}
closedir(DIR);
}
我试图让它递归。 我需要所有的目录和子目录中的所有文件,完整路径,这样我可以在以后打开文件。
但我只输出返回它找到的第一个目录在当前目录中的文件和文件。 如果我有目录内的3个文件夹只显示第一个。
防爆。 CMD通话:
"perl readDir.pl directory=C:/PerlTest/"
谢谢
有许多模块可用于目录中的递归列表文件。
我最喜欢的是文件::查找::规则
use strict ;
use Data::Dumper ;
use File::Find::Rule ;
my $dir = shift ; # get directory from command line
my @files = File::Find::Rule->in( $dir );
print Dumper( \@files ) ;
它发送的文件列表到一个数组(你的程序在做什么)。
$VAR1 = [
'testdir',
'testdir/file1.txt',
'testdir/file2.txt',
'testdir/subdir',
'testdir/subdir/file3.txt'
];
有一个负载的其他选项,如仅列出特别名称的文件。 或者你可以将其设置为一个迭代器,这是在描述如何使用文件::查找
如何使用文件::查找在Perl?
如果你要坚持来与Perl的核心单元,看看文件::查找。
避免轮再造,使用CPAN。
use Path::Class::Iterator;
my $it = Path::Class::Iterator->new(
root => $dir,
breadth_first => 0
);
until ($it->done) {
my $f = $it->next;
push @contents, $f;
}
请确保你不要让人家设置$dir
的东西,可以让他们看看什么地方你不希望他们看。
你的问题是目录范围处理DIR
。 DIR
具有全局范围所以每次递归调用readDir
使用相同的DIR
; 所以,当你closdir(DIR)
并返回给调用者,调用者做了readdir
在一个封闭的目录句柄,一切都停止。 解决的办法是使用本地目录句柄:
sub readDir {
my ($dir) = @_;
opendir(my $dh, $dir) or die $!;
while(my $file = readdir($dh)) {
next if($file eq '.' || $file eq '..');
my $path = $dir . '/' . $file;
if(-d $path) {
readDir($path);
}
push(@contents, $path);
}
closedir($dh);
}
还要注意的是,你会错过一个目录分隔如果(a)它是不是在年底$directory
或(b)在每次递归调用。 据我所知,斜线将在内部转换为在Windows反斜杠,但你可能想使用压延从CPAN模块的路径反正(我只在乎Unix系统,所以我没有任何建议)。
我也建议你传递给一个参考@contents
到readDir
,而不是把它当作一个全局变量,减少错误和减少混乱的方式。 而且不要使用括号sub
,除非你知道他们做什么,他们在做什么的定义。 一些健全检查和清理在$directory
将是一个不错的主意为好。