Directory Handle in Perl Not Working Properly

a 夏天 提交于 2021-02-08 10:58:35

问题


I am trying to read files inside a folder in Perl using Directory Handle. The script is able to show the file name but it is throwing two errors: readdir() attempted on invalid dirhandle DIR and closedir() attempted on invalid dirhandle DIR.

I am calling a subroutine and passing two values:

if($fileEnding eq "directory")
{
  print "$fileName is a directory\n";
  FolderInvestigator1($a, $fileName);
}

$a holds the directory name and its path which is being passed via command-line argument. I am passing the control to a subroutine.

Below is my code:-

sub FolderInvestigator1
{
  my $prevPath = shift;
  my $receivedFolder = shift;
  my $realPath = "$prevPath/$receivedFolder";
  my $path = File::Spec->rel2abs($realPath);
  print "$path\n";
  print "$receivedFolder Folder Received\n";
  opendir(DIR, $path) or die "You've Passed Invalid Directory as Arguments\n";  
  while(my $fileName = readdir DIR)
  {
    next if $fileName =~ /^\./;
    print "The Vacant Folder has $fileName file\n";
  }
  closedir(DIR);
}

Here is my complete code:-

FirstResponder();

sub FirstResponder
{
  if (@ARGV == 0)
  {
    print "No Arguments Passed\n";
  }


else
{
    foreach my $a(@ARGV)
    {
        print "Investigating $a directory below:-\n";

        opendir(DIR, $a) or die "You've Passed Invalid Directory as Arguments\n";                       
        while(my $fileName = readdir DIR)
        {
            next if $fileName =~ /^\./;
            $ending = `file --mime-type $a/$fileName`;
            #print $ending;

            $fileEnding = `basename -s $ending`;                
            #print $fileEnding;
            chomp($fileEnding);
            #print $fileName,"\n";
            if($fileEnding eq "directory")
            {
                print "$fileName is a directory\n";
                FolderInvestigator1($a, $fileName);
            }

            else
            {
                CureExtensions($a, $fileName);
            }       
        }
        closedir(DIR);  
        my @files = glob("$a/*");
        my $size = @files;
        if($size == 0)
        {
            print "The $a is an empty directory\n";
        }   
    }
}#Foreach Ends Here..

}

Please see the screenshot for more information on what's going on!

I am not able to realize why Directory Handle is throwing error even though I made the path correct. Some guidance will be highly appreciated.


回答1:


The problem with your code is that you have a nested use of the bareword (global) dir handle DIR, and hence the inner loop closes the handle before the outer loop is finished:

opendir(DIR, $arg) or die "...";
while(my $fileName = readdir DIR) {
    # ... more code here
    opendir(DIR, $path) or die "...";
    while(my $file = readdir DIR) { 
        # ... more code here
    }
    closedir DIR;
}
closedir DIR;

Here is an example of how you could write the first loop using a lexical dir handle $DIR instead of using a legacy global bareword handle DIR:

use feature qw(say);
use strict;
use warnings;
use File::Spec;

FirstResponder();

sub FirstResponder {
    foreach my $arg (@ARGV) {
        print "Investigating $arg directory below:-\n";
        opendir(my $DIR, $arg) or die "You've Passed Invalid Directory as Arguments\n";
        my $size = 0;
        while(my $fileName = readdir $DIR) {
            next if $fileName =~ /^\./;
            my $path = File::Spec->catfile( $arg, $fileName );
            if( -d $path) {
                print "$fileName is a directory\n";
                say "FolderInvestigator1($arg, $fileName)"
            }
            else {
                say "CureExtensions($arg, $fileName)";
            }
            $size++;
        }
        closedir $DIR;  
        if($size == 0) {
            print "The $arg is an empty directory\n";
        }
    }
}

The use of bareword filehandle names is old style and deprecated, according to perldoc open:

An older style is to use a bareword as the filehandle, as

open(FH, "<", "input.txt")
   or die "Can't open < input.txt: $!";   

Then you can use FH as the filehandle, in close FH and and so on. Note that it's a global variable, so this form is not recommended in new code.

See also:

  • Why does Perl open() documentation use two different FILEHANDLE style?
  • Don't Open Files in the old way


来源:https://stackoverflow.com/questions/61539302/directory-handle-in-perl-not-working-properly

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!