我想获取磁盘上文件的大小(以兆字节为单位)。使用 -s 运算符给出了以字节为单位的大小,但我假设将其除以一个幻数是一个坏主意:

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

我应该只使用只读变量来定义 1024 还是有一种编程方式来获取以千字节为单位的字节数?

编辑: 更新了不正确的计算。

有帮助吗?

解决方案

如果你想避免幻数,试试CPAN模块号码: :字节::人力

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改变某种可变/恒定的不会使此代码的可读性。

嗯,有一个MEG的不是1024字节,有一个在A K 1024个字节和1024 K的一个MEG ...

这是说,1024是一个安全的“神奇”数字,绝不会以任何方式改变,你可以期望你的程序中工作。

我将读此入变量,而不是使用一个幻数。即使幻数是不会改变的,就像个字节的兆字节数,使用良好命名常量是一个很好的做法,因为它使你的代码更易读。这使得它立刻明白,其他人你的意图是什么。

这是一个老问题,已经得到了正确的回答,但以防万一您的程序仅限于核心模块并且您无法使用 数量::字节::人类 这里有我随着时间的推移收集的其他几个选项。我保留它们也是因为每个都使用不同的 Perl 方法,并且是一个很好的例子 蒂姆托维迪:

  • 示例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,也请查看源代码以了解您需要注意的所有内容。

1)你不想1024这就给了你千字节。你想1024 * 1024,或1048576。

2)为什么会用一个神奇的数字将是一个坏主意?它不象在兆字节永远不会改变的数量。不要overthink的东西太多了。

不要误会我的意思,但我认为,宣布1024作为一个魔术变去有点过头了,这是一个有点像“$ ONE = 1; $ TWO = 2;”等

一个千字节以来超过20年被虚报为1024个字节,我严重怀疑,操作系统厂商都不会纠正错误,将其更改为1000。

还有什么意义,虽然是申报非显而易见的东西,如“$兆字节= 1024 * 1024”,因为这是比1048576更具可读性。

由于-s运营商则可能应该做类似的字节返回文件大小

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

和使用int()如果你需要一个全面的身影。它不象KB或MB的尺寸将会在不久的将来随时更改:)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top