Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl';s';readdir';函数结果顺序?_Perl_Readdir - Fatal编程技术网

Perl';s';readdir';函数结果顺序?

Perl';s';readdir';函数结果顺序?,perl,readdir,Perl,Readdir,我在Windows中运行Perl,使用readdir获得目录中所有文件的列表,并将结果存储在数组中。数组中的前两个元素似乎总是“.”和“.”。此顺序有保证吗(假设操作系统不变) 我希望执行以下操作以删除这些值: my $directory = 'C:\\foo\\bar'; opendir my $directory_handle, $directory or die "Could not open '$directory' for reading: $!\n"; my @file

我在Windows中运行Perl,使用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
的顺序没有保证。它

返回由
opendir
打开的目录的下一个目录项

整个过程就是以文件系统提供的任何顺序单步遍历目录中的条目。无法保证此订单是什么

解决这个问题的通常方法是使用正则表达式或字符串等式

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

my @dirs = grep { $_ ne '.' && $_ ne '..' } readdir $dh;
因为这是一个很常见的问题,我建议使用,而不是自己滚动。他们会想出最快、最安全的方法,那就是使用grep过滤
。Path::Tiny修复了许多有关Perl文件和目录处理的问题。

研究了这个问题,Perl向导Randal Schwartz得出结论

Unix上的readdir返回基础原始目录顺序。对目录的添加和删除使用并释放插槽。任何目录的前两个条目始终创建为“点”和“点”,在正常操作下,这些条目永远不会被删除

但是,如果其中任何一个的目录条目被错误地删除(例如,由于损坏,或者使用perl-U选项并让超级用户取消链接),下一次fsck运行必须重新创建该条目,并且只需添加它即可。哦,dot和dotdot不再是前两个条目

因此,防御性编程要求您不要依赖插槽顺序。而且dot和dotdot不能保证是前两个条目,因为Perl无法控制它,而底层操作系统也不能保证


“我看到的所有解决方案都对数组中的每个元素使用正则表达式或if语句,我宁愿不使用这两种方法中的任何一种”为什么不呢?你应该认为所有找到的解决方案都使用这种方法是很重要的。与前导“.”匹配的正则表达式还允许您忽略名称以“.”开头的文件,这是在“nix世界”中隐藏文件的标准方法。@RobK,是的。这就是我一开始问这个问题的原因。:)它们甚至不存在于Windows的根目录中(尽管任何Perl开发人员都应该能够理解简单的正则表达式)。我对此感到害怕。我将研究Path::Tiny->children。谢谢如果您要使用正则表达式,我发现另一种可读性稍高的方法是
/^\.?$/
。您显然没有任何名为“\n”或“..\n”的文件:“
$
只对匹配用户或文件输入有用;在其他任何地方,避免it@ysth虽然我从未在野外见过这样的东西,但从技术上讲,你是对的!原因#1928:不要使用Path::Tiny,它在Windows上可以正常工作。“不适用于ActivePerl”我想你的意思是没有PPM?PPM存储库通常不完整且过时。。。但它甚至是最新的。如果没有,Path::Tiny是一个纯Perl模块,可以安装在ActivePerl上。还考虑切换到它自己的适当配置的编译器和CPAN套件,并与更多的CPAN兼容。