Perl opendir() 只允许一项操作?

Perl opendir() 只允许一项操作?

我发现 perlopendir()函数有一个奇怪的问题,这对我来说毫无意义。

在下面的示例中,perl 将打开 $path 指定的目录并提取所有子目录名称:

opendir(my $dh, $path) or die "can't opendir $path: $!";
my @dirs = grep { ! /^[\.]{1,2}$/ && -d "$path/$_" } readdir($dh);
closedir($dh);
foreach my $d (@dirs) {
   print $encoder->encode($d);
}

在此示例中,perl 将打开 $path 指定的目录并提取所有文件名:

opendir(my $dh, $path) or die "can't opendir $path: $!";
my @files = grep { ! /^[\.]{1,2}$/ && -f "$path/$_" } readdir($dh);
closedir($dh);
foreach my $f (@files) {
   print $encoder->encode($f);
}

但是,我发现下面的代码仅有的打印目录:

opendir(my $dh, $path) or die "can't opendir $path: $!";
my @dirs = grep { ! /^[\.]{1,2}$/ && -d "$path/$_" } readdir($dh);
my @files = grep { ! /^[\.]{1,2}$/ && -f "$path/$_" } readdir($dh);
closedir($dh);

foreach my $f (@files) {
   print $encoder->encode($f);
}
foreach my $d (@dirs) {
   print $encoder->encode($d);
}

grep当交换上例中的两行时,让 perl@files首先分配,perl 将仅有的打印文件。

搞什么?!

我找到了一种解决方法,可以使用以下代码打印文件和目录:

opendir(my $dh, $path) or die "can't opendir $path: $!";
my @dirs = grep { ! /^[\.]{1,2}$/ && -d "$path/$_" } readdir($dh);
closedir($dh);

opendir(my $dh, $path) or die "can't opendir $path: $!";
my @files = grep { ! /^[\.]{1,2}$/ && -f "$path/$_" } readdir($dh);
closedir($dh);

foreach my $f (@files) {
   print $encoder->encode($f);
}
foreach my $d (@dirs) {
   print $encoder->encode($d);
}

但是虽然我可以让我的脚本工作,但我仍然不知道为什么Perl 的行为方式与此处相同。根据我的理解,opendir()打开一个目录并为第一个参数分配一个句柄,该句柄由closedir().那么,如果是这种情况,$dh如果句柄从未关闭,为什么我不能执行多个操作呢?

额外信息:

$ perl --version
This is perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-linux-gnu-thread-multi

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.4 LTS
Release:        18.04
Codename:       bionic

我在 Windows 的 Linux 子系统上运行此代码

答案1

我会用rewinddir两次扫描之间。

Perl 的目录扫描函数(与 Perl 中的许多其他功能一样)是 C 运行时之上的一个薄层。 开幕目录流可以让你阅读条目在一个目录中,一次一个或多个。但一旦读过,这些都是完毕。如果你想再次阅读目录,rewinddir就可以了。

为了进行比较,这里有 POSIX (C) 的链接opendir,readdirrewinddir

相关内容