Perl' readdir'功能结果订单?

时间:2016-05-10 20:31:01

标签: perl readdir

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

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

int main()
{
    DWORD oldp;
    DWORD pd = 0;
    DWORD *pdp = &pd;
    if (!VirtualProtect(pdp, sizeof(DWORD), PAGE_NOACCESS, &oldp))
        return 1;
    return 0;
}

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

2 个答案:

答案 0 :(得分:10)

readdir的顺序无法保证。 The docs state它......

  

返回opendir打开的目录的下一个目录条目。

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

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

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

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

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

答案 1 :(得分:9)

This perlmonks thread from 2001调查了这个问题,Perl精灵Randal Schwartz总结了

  Unix上的 readdir返回基础原始目录顺序。对目录使用和释放插槽的添加和删除。任何目录的前两个条目始终创建为" dot"和" dotdot",这些条目永远不会被删除正常运行

     

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

     

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