我有一个名为 Lib 的文件夹,我使用File :: Find模块在整个目录中搜索该文件夹,D:\
。搜索需要很长时间,如果驱动器有很多子目录,甚至需要5分钟。如何更快地搜索Lib,以便在几秒钟内完成?
我的代码如下所示:
find( \&Lib_files, $dir);
sub Lib_files
{
return unless -d;
if ($_=~m/^([L|l]ib(.*))/)
{
print"$_";
}
return;
}
答案 0 :(得分:20)
在没有预先存在的索引的情况下搜索文件系统是IO绑定的。否则,locate
到Windows Desktop Search之间的产品将不存在。
键入D:\> dir /b/s > directory.lst
并观察该命令运行所需的时间。如果没有首先索引文件,你不应该期望击败它。
您可以做的一项重大改进是减少打印次数。如果您不打算捕获,则不小的改进是不使用捕获括号:
my @dirs;
sub Lib_files {
return unless -d $File::Find::name;
if ( /^[Ll]ib/ ) {
push @dirs, $File::Find::name;
}
return;
}
在我的系统上,一个简单的脚本使用File::Find
打印我的主目录下所有子目录的名称,大约150,000个文件需要几分钟才能运行,而dir %HOME% /ad/b/s > dir.lst
在大约20秒内完成
我倾向于使用:
use File::Basename;
my @dirs = grep { fileparse($_) =~ /^[Ll]ib/ }
split /\n/, `dir %HOME% /ad/b/s`;
在我的系统上在15秒内完成。
如果dir.exe
中可能还有其他%PATH%
,则不会调用cmd.exe
的内置dir
。您可以使用qx! cmd.exe /c dir %HOME% /ad/b/s !
确保调用正确的dir
。
答案 1 :(得分:-1)
如何不使用File :: Find模块
use Cwd;
sub find{
my ($wdir) = shift;
my ($sdir) = &cwd;
chdir($wdir) or die "Unable to enter dir $wdir:$!\n";
opendir(DIR, ".") or die "Unable to open $wdir:$!\n";
foreach my $name (readdir(DIR) ){
next if ($name eq ".");
next if ($name eq "..");
if (-d $name){
&find($name);
next;
}
print $name ."\n";
chdir($sdir) or die "Unable to change to dir $sdir:$!\n";
}
closedir(DIR);
}
&find(".");