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

Is there a way I can query a directory and return a result. Result should indicate if there are files in the directory or not. Thanks.

Replies are listed 'Best First'.
Re: Empty directory
by muppetBoy (Pilgrim) on May 15, 2000 at 17:11 UTC
    You could try something like:
    opendir (DH, "dir-name") or warn $!; @list = readdir (DH); closedir (DH);
    Then check @list to see if any files are present.
    Note Even in an empty directory you should find . and ..
    Hope this helps.
      If you want to check for files only you may do:
      opendir (DIR, $dir) or die "cannot opendir $dir"; my @only_files = grep {-f "$dir/$_"} readdir(DIR); closedir (DIR);
      marcos
RE: Empty directory
by mikfire (Deacon) on May 15, 2000 at 22:13 UTC
    Wow you guys are painful. Why all this grepping and loading an entire directory when all we need to do is something like:
    sub AreThereFiles { opendir DIR, "/path/to/nowhere" or die "That will linger: $!\n"; while ( $foo = readir DIR ) { chomp $foo; next if ( $foo =~ s/^\.\.?$/ ); closedir DIR; return 1; } closedir DIR; return 0; }
    By the very act of reading something other than . or .., we imply the existence of files in that directory. If there are no files, we fall through the loop and return 0.

    This method will be a little slower than slurping it all into an array. But, if your directories look like some of my user's it may not actually be all that slower and the memory savings will be worth it.

    Yes, the closedir calls are likely redundant but I have been bitten a few too many times while recursing directories and I tend to include them from sheer paranoia.

    Mik
    Mik Firestone ( perlus bigotus maximus )

      Let's make that compile :) and not return true if there are only directories:
      sub AreThereFiles { opendir DIR, "/path/to/nowhere" or die "That will linger: $!\n"; while (my $foo = readir DIR ) { chomp $foo; next if ( $foo =~ m/^\.\.?$/ ); next unless (-f $foo); closedir DIR; return 1; } closedir DIR; return 0; }
      I put the -X test in there because the original poster mentioned looking for files. If the existence of a sub-directory is appropriate, you can leave it out.
        Some further nitpicking:
        • It's still readdir not readir :)
        • The chomp is not needed
        • Using $_ instead of my $foo would make things cleaner, i.e.
          next if /^\.\.?$/ or ! -f;
      thanks for pointing out the benefit of minimal resource usage. and you didn't even have any useless uses of scalar (although i think you could safely lose the 'chomp').
RE: Empty directory
by Maqs (Deacon) on May 15, 2000 at 17:35 UTC
    Another way :
    if (scalar `ls $dirname`) {print "Directory $dirname is not empty\n"};

    --
    With best regards
    Maqs.
      1) useless use of scalar

      2) dangerous use of interpolation into a backquoted string, for no real gain

Re: Empty directory
by lhoward (Vicar) on May 15, 2000 at 17:14 UTC
    I'd try something like this...
    sub files_in_dir{ my $dir=shift; opendir D,$dir; my @f=readdir D; closedir D; if(scalar(@f)<=2){ # no files in directory return 0; }else{ # at least 1 file in directory return 1; } }

      You really should check the return status of the opendir and not let the script go any further if it fails.

      How about:

      sub numfiles { opendir D, shift or die "Ugh. $!\n"; grep !/^\.{1,2}$/, readdir D; }
      Why the useless use of scalar? Voodoo? What are you expecting it to do?
Re: Empty directory
by Anonymous Monk on Jan 17, 2002 at 01:54 UTC
    Just another implementation... sub are_there_files { $i = 0; @files = glob (\this\directory\*.*"); foreach $files (@files) { $i++; } if ($i > 0) { $dirvalue = 1; } else { $dirvalue = 0; return; }