2015-02-05 112 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; 
}