2015-02-05 83 views
-2

主题。我试图在不使用查找模块并且不使用du命令的情况下获取目录的大小。以下是我目前正在接近它的方式,但似乎并没有返回正确的尺寸。它返回418836字节,但是当我运行du -s目录大小是141508.Perl - 获取目录大小,但不包含查找或du

my $size = dir_size('wp-content'); 

sub dir_size { 
    my $dir = shift; 
    my $size = 0; 

    opendir(DIR,"$dir"); 

    foreach my $node (grep(!/^\.\.?/,readdir())) { 
    stat($node); 
    if(-f $node) { 
     $size += -s $node; 
    } elsif(-d $node) { 
     $size += dir_size("$dir/$node"); 
    } 
    } 
    closedir(DIR); 

    return $size; 
} 

希望有人能指出我做错了什么。

+0

检查opendir的成功。 – toolic 2015-02-05 17:01:37

+3

通过“查找模块”,我假定你的意思是['File :: Find']](http://perldoc.perl.org/File/Find.html)。你不想使用它的任何特定原因?这是一个核心模块。 – ThisSuitIsBlackNot 2015-02-05 17:06:17

+0

'stat'并不能给你一个特别好的方法,但它可以做到。但在试图重新发明核心模块时要非常小心。 'File :: Find'已经相当成熟,并且可以处理符号链接,各种水果文件名以及各种可以捕捉不必要的东西。 虽然,你真的在​​使用'stat'的结果吗? – Sobrique 2015-02-05 17:10:17

回答

1

这是一个非常基本的解决方案,可以避免File::Find模块。它忽略符号链接以及伪目录...,这可能是您自己的代码问题的来源。它还优化-f,-d-s测试,只需调用stat一次,然后使用伪文件名_

read_size函数返回一个简单的数字,但在打印的字符串的每三位数字前加上逗号,以便对较大的值更易读。

use strict; 
use warnings; 
use 5.010; # For `say` and regex `\K` construct 

my $s = dir_size('wp-content'); 
1 while $s =~ s/ \d+ \K (\d{3}) /,$1/x; 
say $s; 

sub dir_size { 

    my ($dir) = @_; 

    my $size = 0; 

    opendir my ($dh), $dir or die $!; 

    while (my $node = readdir $dh) { 
     next if $node =~ /\A\.\.?\z/; 

     my $fullname = "$dir/$node"; 
     stat $fullname; 

     if (-f _) { 
      $size += -s _; 
     } 
     elsif (-d _) { 
      $size += dir_size($fullname); 
     } 
    } 

    $size; 
}