The first author is one of the current maintainers of today's package from Olivier Thauvin.
Most perl hackers are familiar with the module, File::Find, which has been shipped with the core distribution since 5.000 and works well. File::Find (FF) is used to recursively scan a directory tree and execute user code. Several modules offering a softer, higher-level interfaces to it have cropped up on CPAN such as File::Find::Rule and File::Finder.
File::Find is very robust, but not without its drawbacks. Among its most serious limitations are:
find(\&wanted, $ENV{HOME}) sub wanted{ # Do something with the filename. }Alas, we cannot terminate the find process from within wanted—without resorting to playing around with exceptions—after we've found (only a few instances of) what we were looking for. What would be preferable is an iterative approach that retrieves one file at a time, and can be stopped in the middle.
File::Find::Object (FFO) provides an OO alternative to File::Find which addresses both of these deficiencies. Like FF, the constructor accepts a list of directories to scan which are then traversed one by one. And while FFO provides a backwards compatible callback based interface, the recommended mode of use is to retrieve results via the next() method. Several other esoteric traversal-control functions are also provided:
Our example below is a simple command line application that searches for the first file or directory with a filename matching the supplied certain pattern and reports some information about it.
1 #!/usr/bin/perl 2 3 use strict; 4 use warnings; 5 6 use File::Find::Object; 7 use File::Basename; 8 9 my $pattern_str = shift; 10 my @dirs = @ARGV; 11 12 my $pattern = qr/$pattern_str/; 13 14 my $ff = File::Find::Object->new({}, @dirs); 15 16 my $result; 17 RESULTS_LOOP: 18 while (defined($result = $ff->next())) 19 { 20 if (basename($result) =~ m{$pattern}) 21 { 22 last RESULTS_LOOP; 23 } 24 } 25 26 # Now we've exited from the loop and can do something with $result. 27 28 my @stat = stat($result); 29 print sprintf("Found the file \"%s\" of size %i, modified at %s\n", 30 $result, 31 $stat[7], 32 scalar(localtime($stat[9])) 33 );
There are several similar modules to FFO including File::Find::Iterator, File::Walker and the unmaintained File::FTS. Also of possible interest is Randal L. Schwartz's column that implements directory traversal using a tied hash.