2009-02-04 121 views
12

我想要以兆字節的大小獲取磁盤上的文件大小。使用-s運營商給我的字節大小,但我會認爲然後通過一個神奇的數字除以這是一個壞主意:如何使用Perl以兆字節爲單位獲取文件的大小?

my $size_in_mb = (-s $fh)/(1024 * 1024); 

我應該用一個只讀變量定義1024或者是否有程序化的方式來獲得千字節的字節數?

編輯:更新了錯誤的計算。

回答

29

如果您想避免幻數,請嘗試CPAN模塊Number::Bytes::Human

use Number::Bytes::Human qw(format_bytes); 
my $size = format_bytes(-s $file); # 4.5M 
4

嗯,有一個MEG的不是1024字節,有1024個字節的K和1024 K的一個MEG ...

這就是說,1024是一個安全的「魔術」號永遠不會改變任何系統,你可以預計你的程序工作英寸

+0

一個類似的情況將轉換米和公里之間...你會覺得包括1000的「魔術」因素感覺不好嗎?這是一個永遠不會改變的單位轉換。 – rmeador 2009-02-04 15:21:50

+2

談到營銷..他們有不同的意見(錯了恕我直言,但嘿,他們有更多的錢) – lexu 2009-02-04 15:24:56

1

1)你不想要1024.這給你千字節。你想要1024 * 1024或1048576.

2)爲什麼要除以幻數是一個壞主意?這不像一個兆字節的字節數會改變。不要過多地欺騙事情。

0

不要誤解我的意思,但我認爲將1024作爲Magic Variable聲明有點過分,這有點像「$ ONE = 1; $ TWO = 2;」等

千字節已經被虛報爲1024個字節,因爲超過20年了,我嚴重懷疑,操作系統廠商都不會糾正錯誤,將其更改爲1000

還有什麼意義,雖然正在申報非顯而易見的東西,如「$兆字節= 1024 * 1024」,因爲這是比1048576

1

更具可讀性由於-s操作以字節爲單位,你可能應該做這樣的事情

返回文件大小
my $size_in_mb = (-s $fh)/(1024 * 1024); 

並使用int()如果你需要一個圓形圖。這不像KB或MB的尺寸會在不久的將來隨時改變:)

4

我會將它讀入一個變量中,而不是使用幻數。即使幻數不會改變,就像兆字節中的字節數一樣,但使用一個名爲常量的常量是一個好習慣,因爲它使您的代碼更具可讀性。它使其他人立即明白你的意圖是什麼。

6

你當然可以創建一個函數來計算它。這是比在此實例中創建常量更好的解決方案。

sub size_in_mb { 
    my $size_in_bytes = shift; 
    return $size_in_bytes/(1024 * 1024); 
} 

不需要常量。將1024更改爲某種變量/常量不會使此代碼更具可讀性。

4

這是一個老問題,已被正確回答,但爲了防止您的程序受限於核心模塊,並且您不能在這裏使用Number::Bytes::Human,您還有其他一些隨時間收集的選項。我已經讓他們也因爲每一個使用不同的Perl的做法,是TIMTOWTDI一個很好的例子:

  • 例子1:使用狀態,以避免每次重新初始化變量(perl的5.16之前,你需要使用的功能狀態或的perl -E)

http://kba49.wordpress.com/2013/02/17/format-file-sizes-human-readable-in-perl/

sub formatSize { 
     my $size = shift; 
     my $exp = 0; 

     state $units = [qw(B KB MB GB TB PB)]; 

     for (@$units) { 
      last if $size < 1024; 
      $size /= 1024; 
      $exp++; 
     } 

     return wantarray ? ($size, $units->[$exp]) : sprintf("%.2f %s", $size, $units->[$exp]); 
    } 
  • 實施例2:使用排序映射

sub scaledbytes { 

    # http://www.perlmonks.org/?node_id=378580 
    (sort { length $a <=> length $b 
      } map { sprintf '%.3g%s', $_[0]/1024**$_->[1], $_->[0] 
       }[" bytes"=>0] 
       ,[KB=>1] 
       ,[MB=>2] 
       ,[GB=>3] 
       ,[TB=>4] 
       ,[PB=>5] 
       ,[EB=>6] 
    )[0] 
    } 
  • 實施例3:取的事實,即1 GB = 1024 MB,1MB = 1024 KB和1024 = 2 ** 10:

# http://www.perlmonks.org/?node_id=378544 
my $kb = 1024 * 1024; # set to 1 Gb 

my $mb = $kb >> 10; 
my $gb = $mb >> 10; 

print "$kb kb = $mb mb = $gb gb\n"; 
__END__ 
1048576 kb = 1024 mb = 1 gb 
  • 實施例4:使用的++$n and ... until ..獲取索引用於陣列

# http://www.perlmonks.org/?node_id=378542 
#! perl -slw 
use strict; 

sub scaleIt { 
    my($size, $n) =(shift, 0); 
    ++$n and $size /= 1024 until $size < 1024; 
    return sprintf "%.2f %s", 
      $size, (qw[ bytes KB MB GB ])[ $n ]; 
} 

my $size = -s $ARGV[ 0 ]; 

print "$ARGV[ 0 ]: ", scaleIt $size; 

即使你不能使用數::字節::人力,看看源代碼,看到所有你需要知道的事情。

相關問題