簡體   English   中英

如何使用Perl獲得以兆字節為單位的文件大小?

[英]How do I get the size of a file in megabytes using Perl?

我想獲取磁盤上文件的大小(以兆字節為單位)。 使用-s運算符可以得到以字節為單位的大小,但是我將假定將其除以魔術數字是個壞主意:

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

我應該只使用只讀變量來定義1024,還是可以通過編程方式獲取千字節中的字節數?

編輯:更新了不正確的計算。

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

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

您當然可以創建一個用於計算此函數的函數。 這比在這種情況下創建常量更好。

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

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

這是一個古老的問題,並且已經得到了正確的答案,但是以防萬一您的程序被限制在核心模塊上,並且您無法使用Number :: Bytes :: Human ,隨着時間的推移,您還有其他幾種選擇。 我之所以保留它們,是因為每個人都使用不同的Perl方法,並且是TIMTOWTDI的一個很好的例子:

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

http://kba49.wordpress.com/2013/02/17/format-file-sizes-human-read-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,1 Mb = 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;  

即使您不能使用Number :: Bytes :: Human,也請查看源代碼以查看您需要了解的所有內容。

嗯,兆字節中沒有1024字節,兆字節中沒有1024字節,兆字節中沒有1024 K ...

也就是說,1024是一個安全的“魔術”數字,在可以預期您的程序可以運行的任何系統中,它都不會改變。

我會將其讀入變量而不是使用幻數。 即使幻數不會改變(例如兆字節中的字節數),使用良好命名的常量也是一個好習慣,因為它會使您的代碼更具可讀性。 它使其他人立即知道您的意圖是什么。

1)您不需要1024。這給了您千字節。 您需要1024 * 1024或1048576。

2)為什么除以魔術數字會是個壞主意? 並不是說兆字節中的字節數會改變。 不要想得太多。

不要誤會我的意思,但是:我認為將1024聲明為魔術變量有點太過分了,有點像“ $ ONE = 1; $ TWO = 2;”。 等等

自20多年以來,千字節已被錯誤地聲明為1024字節,我嚴重懷疑操作系統制造商是否會更正該錯誤並將其更改為1000。

不過可能有意義的是聲明非顯而易見的內容,例如“ $ megabyte = 1024 * 1024”,因為它比1048576更具可讀性。

由於-s運算符返回文件大小(以字節為單位),因此您可能應該這樣做

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

如果需要圓形圖形,請使用int()。 這並不意味着KB或MB的大小在不久的將來會隨時發生變化:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM