14

ディスク上のファイルのサイズをメガバイト単位で取得したい。演算子を使用する-sとサイズがバイト単位でわかりますが、これをマジック ナンバーで割るのは悪い考えだと思います。

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

読み取り専用変数を使用して 1024 を定義する必要がありますか、それともキロバイト単位のバイト数をプログラムで取得する方法はありますか?

編集:誤った計算を更新しました。

4

8 に答える 8

33

マジック ナンバーを避けたい場合は、CPAN モジュールNumber::Bytes::Humanを試してください。

use Number::Bytes::Human qw(format_bytes);
my $size = format_bytes(-s $file); # 4.5M
于 2009-02-04T18:25:22.563 に答える
9

これは古い質問であり、すでに正しく回答されていますが、プログラムがコア モジュールに制約されていて、ここでNumber::Bytes::Humanを使用できない場合に備えて、私が時間をかけて収集してきたいくつかの他のオプションがあります。それぞれが異なる Perl アプローチを使用しており、 TIMTOWTDIの良い例であるため、それらも保持しています。

  • 例 1: state を使用して、毎回変数を再初期化するのを回避します (perl 5.16 より前では、feature state または 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、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 を使用できない場合でも、ソース コードを参照して、注意する必要があるすべてのことを確認してください。

于 2014-03-16T09:43:33.660 に答える
7

もちろん、これを計算するための関数を作成することもできます。これは、この場合に定数を作成するよりも優れたソリューションです。

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

定数は必要ありません。1024をある種の変数/定数に変更しても、このコードは読みやすくなりません。

于 2009-02-05T16:18:18.790 に答える
4

マジックナンバーを使用するのではなく、これを変数に読み込みます。メガバイトのバイト数のように魔法数が変わらない場合でも、コードを読みやすくするために、適切な名前の定数を使用することをお勧めします。それはあなたの意図が何であるかを他の人にすぐに明らかにします。

于 2009-02-04T15:34:03.687 に答える
4

ええと、メガには 1024 バイトはありません。K には 1024 バイトがあり、メガには 1024 K があります...

とはいえ、1024 は安全な「魔法の」番号であり、プログラムが動作することが期待できるどのシステムでも決して変更されることはありません。

于 2009-02-04T15:19:44.043 に答える
1

誤解しないでほしいのですが、1024 を Magic Variable として宣言するのは少し行き過ぎだと思います。それは「$ONE = 1; $TWO = 2;」のようなものです。等

1 キロバイトは 20 年以上にわたって 1024 バイトと誤って宣言されてきましたが、オペレーティング システムの製造元がそのバグを修正して 1000 バイトに変更することはないと私は真剣に疑っています。

ただし、「$megabyte = 1024 * 1024」のように、1048576 よりも読みやすいため、自明ではないものを宣言することは理にかなっています。

于 2009-02-04T15:21:57.253 に答える
1

-s 演算子はファイルサイズをバイト単位で返すので、おそらく次のようなことをしているはずです

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

丸い図が必要な場合は int() を使用します。近い将来、KB や MB のサイズが変わるわけではありません :)

于 2009-02-04T15:26:07.260 に答える
1

1)1024は必要ありません。これにより、キロバイトが得られます。1024*1024 または 1048576 が必要です。

2) マジック ナンバーで割るのが悪い考えなのはなぜですか? メガバイトのバイト数が変わるわけではありません。物事を考えすぎないでください。

于 2009-02-04T15:20:51.047 に答える