Question

Je veux obtenir la taille d'un fichier sur le disque en méga-octets. Utilisation de l'opérateur me donne la -s taille en octets, mais je vais supposer que la division alors ce par un nombre magique est une mauvaise idée:

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

Dois-je utiliser une variable en lecture seule pour définir 1024 ou est-il un moyen de programmation pour obtenir la quantité d'octets dans un kilo-octet?

EDIT:. Mise à jour le calcul incorrect

Était-ce utile?

La solution

Si vous souhaitez éviter les numéros magiques, essayez le module CPAN Numéro: :. :: Bytes humaine

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

Autres conseils

Vous pouvez bien sûr créer une fonction de calcul de cette. C'est une meilleure solution que de créer des constantes dans ce cas.

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

Pas besoin de constantes. Modification du à une sorte 1024 de la variable / constante ne sera pas rendre ce code plus lisible.

Eh bien, il n'y a pas 1024 octets dans un meg, il y a 1024 octets dans un K et 1024 K dans un meg ...

Cela dit, 1024 est un nombre « magique » sûr qui ne changera jamais dans tout système que vous pouvez attendre votre programme pour travailler.

Je lisais cela dans une variable plutôt que d'utiliser un nombre magique. Même si les nombres magiques ne vont pas changer, comme le nombre d'octets dans un méga-octet, en utilisant une constante bien nommé est une bonne pratique car il rend votre code plus lisible. Il rend immédiatement évident à tout le monde ce que votre intention est.

Ceci est une question ancienne et a été déjà répondu correctement, mais juste au cas où votre programme est limité aux modules de base et vous ne pouvez pas utiliser TIMTOWTDI :

  • Exemple 1: utilise l'état pour éviter d'initialiser la variable à chaque fois (avant que Perl 5.16 vous devez utiliser l'état de fonctionnalité ou perl -E)

http: // kba49 .wordpress.com / 2013/02/17 / format-tailles de fichiers-lisible en perl humaine /

    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]);
    }
  • Exemple 2: en utilisant la carte de tri

.

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]
  }
  • Exemple 3: Profitez du fait que 1 Go = 1 024 Mo, 1 Mo = 1024 Ko et 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
  • Exemple 4: utilisation de ++$n and ... until .. pour obtenir un index pour le tableau

.

# 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;  

Même si vous ne pouvez pas utiliser le numéro :: Bytes humain, jetez un oeil au code source pour voir toutes les choses que vous devez être au courant.

1) Vous ne voulez pas 1024. Cela vous donne kilooctets. Vous voulez 1024 * 1024, ou 1.048.576.

2) Pourquoi est-ce divisant par un nombre magique est une mauvaise idée? Il est pas comme le nombre d'octets dans un méga-octet ne changera jamais. Ne pas overthink choses trop.

Ne vous méprenez pas, mais: Je pense que déclarant 1024 comme une variable magique va un peu trop loin, c'est un peu comme « $ = 1 UN, DEUX $ = 2; » etc.

Un Kilobyte a été faussement déclaré comme 1024 octets depuis plus de 20 ans, et je doute sérieusement que les fabricants de système d'exploitation jamais corriger ce bug et changer pour 1000.

Ce qui pourrait donner un sens est que de déclarer des choses non évidentes, comme « méga-octet de $ = 1024 * 1024 » puisque c'est plus lisible que 1.048.576.

Depuis l'opérateur -s retourne la taille du fichier en octets, vous devriez probablement faire quelque chose comme

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

et l'utilisation int () si vous avez besoin d'un chiffre rond. Il est pas comme les dimensions de Ko ou Mo va changer à tout moment dans un proche avenir:)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top