Perl 的 'readdir' 函数结果顺序?

Perl's 'readdir' Function Result Order?

我是 运行 Perl in Windows,我正在使用 readdir 获取目录中所有文件的列表,并将结果存储在数组中。数组中的前两个元素似乎总是“.”。和 ”..”。这个顺序是否有保证(假设操作系统不变)?

我想执行以下操作来删除这些值:

my $directory = 'C:\foo\bar';

opendir my $directory_handle, $directory 
    or die "Could not open '$directory' for reading: $!\n";

my @files = readdir $directory_handle;
splice ( @files, 0, 2 ); # Remove the "." and ".." elements from the array

但我担心这样做可能不安全。我见过的所有解决方案都对数组中的每个元素使用正则表达式或 if 语句,如果没有必要,我宁愿不使用这些方法中的任何一种。想法?

readdir顺序不保证。 The docs state 它...

Returns the next directory entry for a directory opened by opendir.

整个过程是按照文件系统提供的任何顺序逐步浏览目录中的条目。无法保证此顺序可能是什么。

解决此问题的常用方法是使用正则表达式或字符串相等。

my @dirs = grep { !/^\.{1,2}\z/ } readdir $dh;

my @dirs = grep { $_ ne '.' && $_ ne '..' } readdir $dh;

因为这是一个很常见的问题,我建议使用 Path::Tiny->children 而不是自己动手。他们会想出最快和最安全的方法,那就是使用 grep 过滤掉 ...。 Path::Tiny 修复了很多关于 Perl 文件和目录处理的问题。

This perlmonks thread from 2001 调查了这个问题,Perl 奇才 Randal Schwartz 得出结论

readdir on Unix returns the underlying raw directory order. Additions and deletions to the directory use and free-up slots. The first two entries to any directory are always created as "dot" and "dotdot", and these entries are never deleted under normal operation.

However, if a directory entry for either of these gets incorrectly deleted (through corruption, or using the perl -U option and letting the superuser unlink it, for example), the next fsck run has to recreate the entry, and it will simply add it. Oops, dot and dotdot are no longer the first two entries!

So, defensive programming mandates that you do not count on the slot order. And there's no promise that dot and dotdot are the first two entries, because Perl can't control that, and the underlying OS doesn't promise it either.