代码之家  ›  专栏  ›  技术社区  ›  Peter Hilton

在Perl中,选择glob而不是readdir(反之亦然)的原因是什么?

  •  62
  • Peter Hilton  · 技术社区  · 7 年前

    这个问题是从 this one . 一些历史:当我第一次学习Perl时,我几乎总是使用 glob 而不是 opendir + readdir 因为我觉得更容易。后来,各种各样的文章和阅读资料表明 格洛布 很糟糕,所以现在我经常使用 雷迪尔 .

    经过深思熟虑 this recent question 我意识到我选择其中一个或另一个的理由可能是谎言。所以,我将列出一些利弊,我希望更有经验的Perl人员能够参与进来并澄清。简言之,有没有令人信服的理由更愿意 格洛布 雷迪尔 雷迪尔 格洛布 (在某些或所有情况下)?

    格洛布 赞成的意见:

    1. 没有点文件(除非您要求)
    2. 保证项目顺序
    3. 不需要手动将目录名预先附加到项上
    4. 更好的名字(来吧- 格洛布 对战 雷迪尔 如果我们只根据名字来判断,那就没有竞争了)
    5. (摘自Yth的回答;参见 格洛布 下面的cons 4)可以返回不存在的文件名:

      @deck = glob "{A,K,Q,J,10,9,8,7,6,5,4,3,2}{\x{2660},\x{2665},\x{2666},\x{2663}}";
      

    格洛布 欺骗:

    1. 旧版本只是简单的破坏(但是“旧”的意思是5.6之前的版本,我认为,坦率地说,如果您使用5.6之前的Perl,您会遇到更大的问题)
    2. 电话 stat 每次(即无用的使用 斯达 在大多数情况下)。
    3. 目录名中的空格有问题(这仍然是真的吗?)
    4. (根据布莱恩的回答)可以返回不存在的文件名:

      $ perl -le 'print glob "{ab}{cd}"'
      

    雷迪尔 赞成的意见:

    1. (来自布莱恩的回答) 打开目录 返回一个文件句柄,您可以在程序中传递它(并重用),但是 格洛布 只返回一个列表
    2. (来自布莱恩的回答) 雷迪尔 是一个适当的迭代器,并为 rewinddir , seekdir ,请 telldir
    3. 更快?(纯粹的猜测基于 格洛布 的功能。无论如何,我并不担心这种优化水平,但这是一种理论上的优势。)
    4. 格洛布 ?
    5. 默认情况下读取所有内容(dotfiles)(这也是一个con)
    6. 可能会说服你不要命名一个文件 0 (另请参见Brad的回答)
    7. 有人吗?Bueller?Bueller?

    雷迪尔 欺骗:

    1. 如果您不记得预先输入目录名,您可以 尝试进行文件测试、复制项目或编辑项目或…
    2. 如果你不记得 grep . .. 项目,你 当你计算项目的时候,或者尝试递归地沿着文件树走,或者…
    3. 我有没有提到预先填写目录名?(旁注,但我在Perl初学者邮件列表中的第一篇文章是经典的,“为什么这个涉及文件测试的代码在某些时候不起作用?”与此相关的问题。显然,我还是很苦。)
    4. 物品不按特定顺序退回。这意味着你必须经常记住以某种方式对它们进行分类。(如果这意味着更快的速度,如果这意味着你实际上 认为 关于如何以及是否需要对项目进行排序。) 编辑 :非常小的样本,但在Mac电脑上 雷迪尔 按字母顺序返回项,不区分大小写。在Debian Box和OpenBSD服务器上,顺序是完全随机的。我用苹果的内置Perl(5.8.8)和我自己编译的5.10.1测试了Mac。Debian Box为5.10.0,OpenBSD机器也是如此。我想知道这是否是一个文件系统问题,而不是Perl?
    5. 默认情况下读取所有内容(dotfiles)(这也是一个pro)
    6. 不一定能很好地处理名为 (另见专业人士-见布拉德的回答)
    10 回复  |  直到 9 年前
        1
  •  43
  •   Sinan Ünür    10 年前

    glob opendir

     sub use_any_dir_handle {
          my( $dh ) = @_;
          rewinddir $dh;
          ...do some filtering...
          return \@files;
          }
    

    seekdir

    • $ perl -le 'print glob "{ab}{cd}"'
      
        2
  •  8
  •   ysth    10 年前

    my @deck = List::Util::shuffle glob "{A,K,Q,J,10,9,8,7,6,5,4,3,2}{\x{2660},\x{2665},\x{2666},\x{2663}}";
    while (my @hand = splice @deck,0,13) {
        say join ",", @hand;
    }
    __END__
    6♥,8♠,7♠,Q♠,K♣,Q♦,A♣,3♦,6♦,5♥,10♣,Q♣,2♠
    2♥,2♣,K♥,A♥,8♦,6♠,8♣,10♠,10♥,5♣,3♥,Q♥,K♦
    5♠,5♦,J♣,J♥,J♦,9♠,2♦,8♥,9♣,4♥,10♦,6♣,3♠
    3♣,A♦,K♠,4♦,7♣,4♣,A♠,4♠,7♥,J♠,9♥,7♦,9♦
    
        3
  •  6
  •   Brad Gilbert    16 年前

    opendir readdir

    {
      open my $file, '>', 0;
      print {$file} 'Breaks while( readdir ){ ... }'
    }
    opendir my $dir, '.';
    
    my $a = 0;
    ++$a for readdir $dir;
    print $a, "\n";
    
    rewinddir $dir;
    
    my $b = 0;
    ++$b while readdir $dir;
    print $b, "\n";
    

    0 251 188

    use 5.10.0;
    opendir my $dir, '.';
    
    say while readdir $dir;
    

    use 5.10.0;
    my $a = 0;
    ++$a for glob '*';
    say $a;
    
    my $b = 0;
    ++$b while glob '*';
    say $b;
    
    say for glob '*';
    say while glob '*';
    

    while( readdir $dir ){ ... }
    

    while( defined( $_ = readdir $dir ){ ...}
    

    read if

        4
  •  5
  •   itub    16 年前

    glob glob "*/*/*"

        5
  •  4
  •   Telemachus MrJames    10 年前

    glob opendir readdir

        6
  •  3
  •   Robert P    16 年前

    glob

    readdir

        7
  •  2
  •   mob    16 年前

    readdir grep glob

        8
  •  2
  •   Telemachus MrJames    16 年前

    say for glob "*";
    
    --output:--
    1perl.pl
    2perl.pl
    2perl.pl.bak
    3perl.pl
    3perl.pl.bak
    4perl.pl
    data.txt
    data1.txt
    data2.txt
    data2.txt.out
    

    glob

    readdir

    chdir ("../..");  
    say for glob("*");
    
        9
  •  2
  •   sam    13 年前

    File::Slurp read_dir

    err_mode prefix keep_dot_dot

        10
  •  1
  •   JensJ    14 年前

    Perl Cookbook

    glob dosglob opendir readdir closedir

    推荐文章