如何使用 Perl 获取文件大小(以兆字节为单位)?
-
21-08-2019 - |
题
我想获取磁盘上文件的大小(以兆字节为单位)。使用 -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的尺寸将会在不久的将来随时更改:)