4

我有一个名为Lib的文件夹,我正在使用 File::Find 模块在整个目录中搜索该文件夹,例如D:\. 搜索需要很长时间,如果驱动器有很多子目录,甚至需要 5 分钟。如何更快地搜索该 Lib,以便在几秒钟内完成?

我的代码如下所示:

    find( \&Lib_files, $dir);
    sub Lib_files
    {
       return unless -d;
      if ($_=~m/^([L|l]ib(.*))/)
      {
          print"$_";
      }
      return;
    }
4

2 回答 2

21

Searching the file system without a preexisting index is IO bound. Otherwise, products ranging from locate to Windows Desktop Search would not exist.

Type D:\> dir /b/s > directory.lst and observe how long it takes for that command to run. You should not expect to beat that without indexing files first.

One major improvement you can make is to print less often. A minor improvement is not to use capturing parentheses if you are not going to capture:

my @dirs;

sub Lib_files {
   return unless -d $File::Find::name; 
   if ( /^[Ll]ib/ ) {
        push @dirs, $File::Find::name;
   }
   return;
}

On my system, a simple script using File::Find to print the names of all subdirectories under my home directory with about 150,000 files takes a few minutes to run compared to dir %HOME% /ad/b/s > dir.lst which completes in about 20 seconds.

I would be inclined to use:

use File::Basename;

my @dirs = grep { fileparse($_) =~ /^[Ll]ib/ }
           split /\n/,  `dir %HOME% /ad/b/s`;

which completed in under 15 seconds on my system.

If there is a chance there is some other dir.exe in %PATH%, cmd.exe's built-in dir will not be invoked. You can use qx! cmd.exe /c dir %HOME% /ad/b/s ! to make sure that the right dir is invoked.

于 2009-11-23T15:02:24.983 回答
-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(".");
于 2009-11-24T03:10:08.103 回答