Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks!
I need to ready files in some directories and I found a short way of doing this, any better way please let me know. But my question is I am trying to ready all the fiels into the "@array" but when I print this array not all the files are there, what am I missing here? I would like some comments on how I am calling this sub here:
setup($_) for @directories;
Here is the code:
#!usr/bin/perl use strict; use warnings; my @directories = ( '/dir1', '/dir1/imgs' ); my @files; setup($_) for @directories; sub setup { my $dir = shift; @files = file_list($dir); } my $c; foreach my $file(@files) { $c++; print "\n$c - $file\n"; } sub file_list { my $directory = shift; opendir( DIR, $directory ) or die "Can't open $directory: $!"; my @files = grep( !/^\.\.?$/, readdir(DIR) ); closedir(DIR); return @files; }
Thanks for looking!

Replies are listed 'Best First'.
Re: Reading Multiple Directories
by jwkrahn (Abbot) on Aug 25, 2011 at 14:07 UTC

    You are assigning to @files first from '/dir1' and then you assign to @files from '/dir1/imgs' overwriting the original contents.    You need to use push instead of assignment.

Re: Reading Multiple Directories
by toolic (Bishop) on Aug 25, 2011 at 14:19 UTC
    Another way to get a list of files is to use grep and -f:
    use warnings; use strict; use Data::Dumper; use File::Slurp qw(read_dir); my @files; my @directories = ( '/dir1', '/dir1/imgs' ); for my $d (@directories) { push @files, grep { -f "$d/$_" } read_dir($d); } print Dumper(\@files);
    Also, File::Slurp automatically excludes the special dot directories (. and ..) for you. There is no need for you to explicitly get rid of them.
      I like this way better, it seems to have less over head or code any way, but I need to do one more test before "pushing" the files into @files. Test for file size, trying this way, but not really sure if its efficient.
      use warnings; use strict; use Data::Dumper; use File::Slurp qw(read_dir); my @files; my @directories = ( '/dir1', '/dir1/imgs' ); for my $d (@directories) { push @files, grep { -f "$d/$_" } read_dir($d); foreach my $file(@files) { my $filesize = -s $d.$file; #need to check if file is > then 0 and less then 2M; } }
      Thanks once again!
Re: Reading Multiple Directories
by jdrago999 (Pilgrim) on Aug 25, 2011 at 17:26 UTC

    Going for brevity here...

    #!/usr/bin/perl -w use strict; use warnings 'all'; my $min_size = 1024; my @dirs = qw( /dir1 /dir1/imgs ); my @files = grep { -f && -s >= $min_size } # Check size map { $_ =~ s{//}{/}g; $_ } # Remove extra slashes map { <$_/*> } @dirs; # Read directory warn join "\n", @files;
Re: Reading Multiple Directories
by locked_user sundialsvc4 (Abbot) on Aug 26, 2011 at 14:15 UTC

    As an aside, another thing that you have to really watch-out for is that many operating systems do not handle having many directory searches going on at the same time.   I remember first encountering this years ago in Windows, and encountering it over and over since then.   You just can’t have too many nested, or simultaneous directory walk-thrus going on at the same time, and (Windows’) behavior in that context is sometimes not to throw an error-message ... it just does the wrong thing.   Caveat coder.   The workaround is to stash the file-and-directory names and to do a series of lookups one after the other.