Domanda

Voglio ottenere la dimensione di un file su disco in megabyte. Utilizzando l'operatore -s mi dà la dimensione in byte, ma ho intenzione di assumere che poi dividere questo da un numero magico è una cattiva idea:

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

Dovrei usare una sola lettura variabile per definire 1024 o c'è un modo programmatico per ottenere la quantità di byte in un kilobyte?

EDIT:. Aggiornato il calcolo errato

È stato utile?

Soluzione

Se vuoi evitare di numeri magici, provare il CPAN numero del modulo : :. Byte :: umana

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

Altri suggerimenti

Si potrebbe comunque creare una funzione per il calcolo di questo. Questa è una soluzione migliore rispetto alla creazione di costanti in questo caso.

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

Non c'è bisogno di costanti. Cambiare il 1024 a qualche tipo di variabile / costante non farà questo codice più leggibile.

Beh, non c'è 1024 byte in un meg, c'è 1024 byte in un K e 1024 K in un meg ...

Detto questo, 1024 è un numero sicuro "magico" che non cambierà mai in qualsiasi sistema si può aspettare il vostro programma per lavorare in.

Vorrei leggere questo in una variabile piuttosto che utilizzare un numero magico. Anche se i numeri magici non stanno andando a cambiare, come il numero di byte in un megabyte, con un pozzo di nome costante è una buona pratica perché rende il codice più leggibile. Lo rende immediatamente evidente a tutti gli altri ciò che la vostra intenzione è.

Questa è una vecchia questione ed è stato già risposto in modo corretto, ma solo nel caso in cui il programma è limitato ai moduli di base e non è possibile utilizzare numero :: :: Bytes umana qui si hanno molte altre opzioni che sono stati raccolti nel corso del tempo. Ho mantenuto loro anche perché ognuno utilizzano un diverso approccio Perl ed è un bell'esempio per TIMTOWTDI :

  • Esempio 1: si avvale di evitare reinizializzare la variabile ogni volta (prima di Perl 5.16 è necessario utilizzare stato di funzionalità o Perl -E)

http: // kba49 .wordpress.com / 2013/02/17 / formato-file-dimensioni-leggibile-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]);
    }
  • Esempio 2: utilizzo sorta mappa

.

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]
  }
  • Esempio 3: Approfittate del fatto che 1 Gb = 1024 MB, 1 Mb = 1024 Kb e 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
  • Esempio 4: uso di ++$n and ... until .. per ottenere un indice per l'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;  

Anche se non è possibile utilizzare il numero :: :: Bytes umana, date un'occhiata al codice sorgente per vedere tutte le cose che avete bisogno di essere a conoscenza.

1) Non si vuole 1024. Che ti dà kilobyte. Volete 1024 * 1024 o 1048576.

2) Perché dovrebbe dividere per un numero magico essere una cattiva idea? Non è come il numero di byte in un megabyte potrà mai cambiare. Non overthink troppo le cose.

Non fraintendetemi, ma: penso che dichiarare 1024 come una variabile magia va un po 'troppo lontano, che è un po' come "$ ONE = 1; $ DUE = 2;" ecc.

Un Kilobyte è stato falsamente dichiarato come 1024 byte da più di 20 anni, e ho seriamente dubitare che i produttori di sistemi operativi potrà mai correggere quel bug e modificarlo a 1000.

Che cosa potrebbe avere un senso se è dichiarare cose non ovvio, come "$ megabyte = 1024 * 1024", dal momento che è più leggibile rispetto a 1048576.

Dal momento che l'operatore -s restituisce la dimensione del file in byte si dovrebbe probabilmente fare qualcosa come

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

e l'uso int () se avete bisogno di una cifra tonda. Non è come le dimensioni di KB o MB sta per cambiare in qualunque momento in un prossimo futuro:)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top