可以指定搜索层次。
避免了循环访问。 (如果目录里有链接指向其他的目录,就有可能导致循环访问。这里用设备号可以识别出已经访问的目录,从而避免循环访问)
可以指定跳过某些特定目录。
$path : 要搜索的起始目录
$level: 要搜索的层次
/&func: 函数地址 (用户自定义的函数,对搜索到的文件进行处理)
$param_r: 传递给函数的参数
$skip_dir: 要跳过的特定目录。 (可以指定多个目录,用空格分开)
package BW_DIR;
# sub scanDir($path,$level,/&func,$param_r,$skip_dir)
# $level = 0 means only search one level dir/xx
# 1 search 2 level dir/xx/xx
# 2 search 3 level dir/xx/xx/xx
sub scanDir
{
my ($path,$level,$func,$param_r,$skip_dir) = @_;
my @list;
my %visited;
my @tmp = split ///+/,"$path";
$level += @tmp;
my %skips;
@tmp = split /[,/s+]/,$skip_dir;
foreach (@tmp)
{
$skips{$_} = 1;
}
push(@list, $path);
while(@list >0)
{
my $item = shift (@list);
if( -d $item)
{
my ($devno, $ino) = (stat("$item"))[0,1];
if(defined $visited{"$devno:$ino"})
{
#print "Warning: the dir /"$item/" has been visited! Will bypass it./n";
next;
}
#it's a dir
if(opendir(MYDIR,$item))
{
my @entry = readdir(MYDIR);
closedir(MYDIR);
foreach (@entry)
{
if($_ eq "." || $_ eq ".." || $_ eq "lost+found")
{
next;
}
if(-d "$item/$_")
{
@tmp = split ///+/,"$item/$_";
if((@tmp <= $level)&& !defined $skips{$_})
{
push(@list,"$item/$_");
}
}elsif(-f "$item/$_")
{
if(defined $func)
{
&$func("$item/$_",$param_r);
}
}
}
# we have visited this dir, mark it;
($devno, $ino) = (stat("$item"))[0,1];
$visited{"$devno:$ino"} = 1;
}
}elsif (-f $item)
{
if(defined $func)
{
&$func($item,$param_r);
}
}
}
}