Perl中的目录句柄无法正常工作 [英] Directory Handle in Perl Not Working Properly
问题描述
我正在尝试使用Directory Handle在Perl中的文件夹中读取文件.该脚本能够显示文件名,但会引发两个错误:尝试对无效的dirhandle DIR进行 readdir()
和尝试对无效的dirhandle DIR 进行的 closedir().
.>
我正在调用一个子例程并传递两个值:
if($ fileEnding eq目录"){打印"$ fileName是目录\ n";FolderInvestigator1($ a,$ fileName);}
$ a
包含目录名称及其通过命令行参数传递的路径.我正在将控件传递给子例程.
以下是我的代码:-
sub FolderInvestigator1{我的$ prevPath = shift;我的$ receivedFolder = shift我的$ realPath ="$ prevPath/$ receivedFolder";我的$ path = File :: Spec-> rel2abs($ realPath);打印"$ path \ n";打印"$ receivedFolder Folder Received \ n";opendir(DIR,$ path)或死于您已将无效目录作为参数传递给\ n";while(我的$ fileName = readdir DIR){接下来如果$ fileName =〜/^\./;打印空文件夹有$ fileName文件\ n";}closeir(DIR);}
这是我完整的代码:-
FirstResponder();子FirstResponder{如果(@ARGV == 0){打印未传递参数\ n";}别的{foreach我的$ a(@ARGV){打印在下面调查$ a目录:-\ n";opendir(DIR,$ a)或死于您已将无效目录作为参数传递给\ n";while(我的$ fileName = readdir DIR){接下来如果$ fileName =〜/^\./;$ ending =`file --mime-type $ a/$ fileName`;#print $ end;$ fileEnding =`basename -s $ ending`;#print $ fileEnding;chomp($ fileEnding);#print $ fileName,"\ n";if($ fileEnding eq目录"){打印"$ fileName是目录\ n";FolderInvestigator1($ a,$ fileName);}别的{CureExtensions($ a,$ fileName);}}closeir(DIR);我的@files = glob("$ a/*");我的$ size = @files;if($ size == 0){打印"$ a是一个空目录\ n";}}} #Foreach在这里结束.
}
请查看屏幕截图,以获取有关正在发生的事情的更多信息!
即使我将路径正确设置,我也无法理解目录句柄为何引发错误.一些指导将不胜感激.
您的代码存在的问题是您嵌套使用了裸字(全局)目录句柄 DIR
,因此内部循环在外循环完成之前关闭句柄:
opendir(DIR,$ arg)或死于"...";while(我的$ fileName = readdir DIR){#...更多代码在这里opendir(DIR,$ path)或死于"...";while(我的$ file = readdir DIR){#...更多代码在这里}封闭目录DIR;}封闭目录DIR;
这里是一个示例,说明如何使用词法目录句柄 $ DIR
而不是使用遗留的全局裸字句柄 DIR
:
使用功能qw(say);使用严格使用警告;使用File :: Spec;急救人员();子FirstResponder {foreach我的$ arg(@ARGV){打印在下面调查$ arg目录:-\ n";opendir(我的$ DIR,$ arg)或死于您已将无效目录作为参数传递给\ n";我的$ size = 0;while(我的$ fileName = readdir $ DIR){接下来如果$ fileName =〜/^\./;我的$ path = File :: Spec-> catfile($ arg,$ fileName);if(-d $ path){打印"$ fileName是目录\ n";说"FolderInvestigator1($ arg,$ fileName)"}别的 {说"CureExtensions($ arg,$ fileName)";}$ size ++;}$ DIR;if($ size == 0){打印"$ arg是一个空目录\ n";}}}
根据 perldoc open ,使用裸字文件句柄名称已过时并已弃用.>:
一种较旧的样式是使用裸词作为文件句柄,例如
open(FH,<","input.txt")或死于无法打开< input.txt:$!";
然后,您可以将FH用作文件句柄,关闭FH等等.请注意,这是全球性的变量,因此不建议在新代码中使用这种形式.
另请参阅:
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.
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
这篇关于Perl中的目录句柄无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!