Pregunta

Quiero obtener el tamaño de un archivo en disco en megabytes. Usando el operador -s me da el tamaño en bytes, pero voy a asumir que luego dividiendo este por un número mágico es una mala idea:

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

¿Debo usar un solo lectura variable para definir 1024 o hay una manera programática para obtener la cantidad de bytes en un kilobyte?

EDIT:. Se ha actualizado el cálculo incorrecto

¿Fue útil?

Solución

Si desea evitar números mágicos, prueba el número de módulo CPAN: :. :: Bytes humano

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

Otros consejos

Se podría, por supuesto, crear una función para calcular esto. Esto es una solución mejor que la creación de las constantes en este caso.

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

No hay necesidad de constantes. Cambio de la 1024 a algún tipo de la variable / constante no hará que este código sea más legible.

Bueno, no hay 1024 bytes en un meg, hay 1024 bytes en un K y 1024 K en un meg ...

Dicho esto, 1024 es un número de seguro "mágica" que nunca va a cambiar en cualquier sistema se puede esperar que su programa para trabajar en.

Me gustaría leer esto en una variable en lugar de utilizar un número mágico. Incluso si los números mágicos no van a cambiar, al igual que el número de bytes de un megabyte, utilizando una constante así llamado es una buena práctica porque hace que el código sea más legible. Se hace evidente de inmediato a todos los demás lo que su intención es.

Esta es una cuestión de edad y ha sido ya contestadas correctamente, pero en caso de que su programa está limitado a los módulos básicos y no se puede utilizar número :: :: Bytes humano aquí tienes varias opciones que se han recogido en el tiempo. He guardado ellos también porque cada uno de ellos utilizan un enfoque diferente y Perl es un buen ejemplo para TIMTOWTDI :

  • Ejemplo 1: utiliza el estado para evitar reinicializar la variable cada vez (antes de Perl 5.16 es necesario utilizar estado de la función o Perl -E)

http: // kba49 .wordpress.com / 2013/02/17 / formato de tamaños de archivos-legible-en-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]);
    }
  • Ejemplo 2: uso de un mapa tipo

.

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]
  }
  • ejemplo 3: Aprovechar el hecho de que 1 Gb = 1,024 Mb, 1 Mb = 1,024 Kb y 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
  • ejemplo 4: uso de ++$n and ... until .. para obtener un índice para el array

.

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

Incluso si no se puede usar el Número de Bytes :: :: humana, tomar un vistazo al código fuente para ver todas las cosas que usted necesita para tener en cuenta.

1) Usted no quiere 1024. Eso le da kilobytes. ¿Quieres 1024 * 1024 o 1048576.

2) ¿Por qué dividir por un número mágico ser una mala idea? No es como el número de bytes en un megabyte va a cambiar. No lo pienses demasiado las cosas.

No me malinterpreten, pero: Creo que la declaración de 1024 como una variable mágica va un poco demasiado lejos, eso es un poco como "UNO $ = 1; $ DOS = 2;" etc.

Un kilobyte ha sido declarado falsamente como 1024 bytes desde hace más de 20 años, y tengo serias dudas de que los fabricantes de sistemas operativos serán siempre corregir ese error y el cambio a 1000.

Lo que podría tener sentido, aunque es declarar cosas no evidentes, como "$ megabyte = 1024 * 1024", ya que es más fácil de leer que 1.048.576.

Dado que el operador -s devuelve el tamaño del archivo en bytes que probablemente debería estar haciendo algo como

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

y el uso int () si necesita una figura redonda. No es como las dimensiones de KB o MB va a cambiar en cualquier momento en el futuro cercano:)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top