visual studio microsoft español descargar community perl file-io filesize magic-numbers

studio - ¿Cómo obtengo el tamaño de un archivo en megabytes usando Perl?



visual studio installer (8)

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

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

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

EDITAR: actualizó el cálculo incorrecto.


1) No quieres 1024. Eso te da kilobytes. Quiere 1024 * 1024 o 1048576.

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


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

Dicho esto, 1024 es un número "mágico" seguro que nunca cambiará en ningún sistema en el que pueda esperar que funcione su programa.


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

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

y use int () si necesita una figura redonda. No es que las dimensiones de KB o MB vayan a cambiar en el futuro cercano :)


Leería esto en una variable en lugar de usar un número mágico. Incluso si los números mágicos no van a cambiar, como el número de bytes en un megabyte, usar una constante bien llamada es una buena práctica porque hace que su código sea más legible. De inmediato es evidente para todos los demás cuál es tu intención.


No me malinterpreten, pero: creo que declarar 1024 como una Variable Mágica va demasiado lejos, es algo así como "$ ONE = 1; $ TWO = 2;" etc.

Un Kilobyte ha sido declarado falsamente como 1024 Bytes desde hace más de 20 años, y dudo seriamente que los fabricantes del sistema operativo alguna vez corrijan ese error y lo cambien a 1000.

Lo que podría tener sentido es declarar cosas no obvias, como "$ megabyte = 1024 * 1024", ya que es más legible que 1048576.


Si quieres evitar los números mágicos, prueba el número de CPAN Number :: Bytes :: Human .

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


Por supuesto, puede crear una función para calcular esto. Esa es una solución mejor que crear constantes en esta instancia.

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

Sin necesidad de constantes. Cambiar el 1024 a algún tipo de variable / constante no hará que este código sea más legible.


Esta es una pregunta antigua y ya ha sido respondida correctamente, pero en caso de que su programa esté restringido a los módulos centrales y no pueda usar Number :: Bytes :: Human, aquí tiene varias otras opciones que he recopilado con el tiempo. Los he guardado también porque cada uno usa un enfoque diferente de Perl y es un buen ejemplo para TIMTOWTDI :

  • ejemplo 1: usa el estado para evitar reiniciar la variable cada vez (antes de Perl 5.16 necesita usar el estado de la característica o 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]); }

  • ejemplo 2: utilizando un mapa de clasificación

.

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: aproveche el hecho de que 1 Gb = 1024 Mb, 1 Mb = 1024 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 la matriz

.

# 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 puede usar Number :: Bytes :: Human, eche un vistazo al código fuente para ver todo lo que necesita saber.