m.bedekar has asked for the wisdom of the Perl Monks concerning the following question:

hi, I have a problem in accessing directory tree in perl. I open a directory using opendir and then use readdir to read inside the directory. But that directory may contain subdirectory or subdirectories and these subdirectories may contain subdirectories and so on. Is it possible in perl that if i open and read a directory , i can also read files inside its subdirectories? Please help.

Replies are listed 'Best First'.
Re: Getting files in a directory tree
by jweed (Chaplain) on Mar 04, 2004 at 05:11 UTC
Re: Getting files in a directory tree
by graff (Chancellor) on Mar 04, 2004 at 05:20 UTC
Re: Getting files in a directory tree
by arden (Curate) on Mar 04, 2004 at 05:10 UTC
    m.bedekar, as I said in the Chatterbox, not directly, but you can open the subdirectories as another filehandle (or even the same one if you do it recursively in a different scope) and read in the contents of that directory.

    Since you didn't provide any code, I won't either, because I'm assuming that you know how to opendir() & readdir(). If you need more help, please give us an idea of what you've already tried. Take a look here: How (Not) To Ask A Question first/again too please. . .

    - - arden.

    ps. I left off mention about Find::File because you previously said it was too slow for your desires.

Re: Getting files in a directory tree
by BUU (Prior) on Mar 04, 2004 at 05:20 UTC
    Just to provide an alternative,
    sub recurse { my $d = shift; opendir D,$d; # who needs error checking anyways while(<D>) { if( -d $_ ){ recurse($_); else{ #regular file } } }
      Beware of the side effects of the Perl built-in variables, your solution is not likely going to work as you expected, the $_ will get clobberred in your recursion and you will sit there scratching your head for hours trying to find out what's going wrong. :-)

      1. do not forget to close the directory using closedir
      2. using recursion and D as the directory handle can be danagerous; better
      sub recurse { my $folder = shift; my $dir; if(opendir($dir, $folder)) # who needs error checking anyways? me! { while(defined(my $entry = readdir($dir))) { next if $entry =~ /^\.\.?$/; # avoiding endless loop :) if( -d "$folder/$entry" ){ recurse("$folder/$entry"); } else { #regular file } } closedir($dir); } }
Re: Getting files in a directory tree
by Roger (Parson) on Mar 04, 2004 at 06:10 UTC
    The following works fine if you only want to look 1 level beneath the directory, ie., no recursion of sub-directories:
    use strict; use warnings; opendir my $dir, "." or die "Can not open directory: $!"; while ($_ = readdir $dir) { my $mode = (stat $_)[2] >> 15; print "$_ : ", $mode ? "file" : "directory", "\n" } closedir $dir;

    If you want to recurse the sub-directories:
    use strict; use warnings; use File::Find; find(\&wanted, "L:/Perl"); sub wanted { return if substr($_, 0, 1) eq '.'; my $path = "$File::Find::dir/$_"; my $mode = (stat $path)[2] >> 15; print "$path is ", $mode ? "file" : "dir", "\n"; }

Re: Getting files in a directory tree
by crabbdean (Pilgrim) on Mar 04, 2004 at 08:44 UTC
    Be wary of the File::Find module, its has a memory leak. I discovered it while writing a program to traverse our file server. It eventually crashed our server. See File::Find memory leak

    That prompted this solution An alternative to File::Find as an alternative.

    Dean

    Programming these days takes more than a lone avenger with a compiler. - sam
Re: Getting files in a directory tree
by crabbdean (Pilgrim) on Mar 04, 2004 at 13:05 UTC
    In addition to using the An alternative to File::Find for directory traversing also see the node Re: Re: Re: Importing external dependencies into source that I just wrote on compiling your Perl source and the GNU find.exe into a single executable to remove the external dependencies. Together the two offer a complete single source solution without using File::Find.

    Enjoy!
    Dean

    Programming these days takes more than a lone avenger with a compiler. - sam