在Perl里处理目录时,我们常常拿到一堆条目,却分不清哪一个是普通文件,哪一个是子目录。其实Perl自带了非常方便的文件测试操作符,可以帮我们直接判断。

使用文件测试操作符
Perl的-f和-d是最常用的两个测试符。-f表示是否为普通文件,-d表示是否为目录。结合opendir与readdir就能过滤。
use strict;
use warnings;
my $dir = './test_dir';
opendir(my $dh, $dir) or die "无法打开目录: $!";
while (my $entry = readdir $dh) {
next if ($entry eq '.' || $entry eq '..');
my $path = "$dir/$entry";
if (-f $path) {
print "$entry 是一个文件n";
} elsif (-d $path) {
print "$entry 是一个目录n";
} else {
print "$entry 是其他类型n";
}
}
closedir $dh;
使用stat函数
如果不想记那么多操作符,也可以用stat函数拿到 inode 信息,其中模式字段的位掩码能区分类型。
use strict;
use warnings;
my $path = './test_dir/some_item';
my ($mode) = (stat($path))[2];
if ($mode & 0170000) {
my $type = $mode & 0170000;
if ($type == 0100000) {
print "这是普通文件n";
} elsif ($type == 0040000) {
print "这是目录n";
}
}
使用File::Spec拼接路径
为了跨平台安全,推荐用File::Spec来拼路径,再配合-f和-d判断。
use strict;
use warnings;
use File::Spec;
my $dir = './test_dir';
opendir(my $dh, $dir) or die $!;
while (my $entry = readdir $dh) {
next if $entry =~ /^..?$/;
my $full = File::Spec->catfile($dir, $entry);
print "$entry => ", (-f $full ? '文件' : -d $full ? '目录' : '其他'), "n";
}
closedir $dh;
小结
从Perl的目录中分辨文件,最简单就是用-f和-d测试操作符。遍历用opendir、readdir,路径拼接注意跨平台。掌握这几招,目录处理就清晰多了。