Forma correcta de convertir el tamaño en bytes a KB, MB, GB en JavaScript

Resuelto l2aelba asked hace 11 años • 34 respuestas

Obtuve este código para convertir el tamaño en bytes a través de PHP.

Ahora quiero convertir esos tamaños a tamaños legibles por humanos usando JavaScript. Intenté convertir este código a JavaScript, que se ve así:

function formatSizeUnits(bytes){
  if      (bytes >= 1073741824) { bytes = (bytes / 1073741824).toFixed(2) + " GB"; }
  else if (bytes >= 1048576)    { bytes = (bytes / 1048576).toFixed(2) + " MB"; }
  else if (bytes >= 1024)       { bytes = (bytes / 1024).toFixed(2) + " KB"; }
  else if (bytes > 1)           { bytes = bytes + " bytes"; }
  else if (bytes == 1)          { bytes = bytes + " byte"; }
  else                          { bytes = "0 bytes"; }
  return bytes;
}

¿Es esta la forma correcta de hacer esto? hay una manera mas facil?

l2aelba avatar Apr 09 '13 18:04 l2aelba
Aceptado

De esto: ( fuente )


No minificado y ES6'ed: (por la comunidad)

function formatBytes(bytes, decimals = 2) {
    if (!+bytes) return '0 Bytes'

    const k = 1024
    const dm = decimals < 0 ? 0 : decimals
    const sizes = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']

    const i = Math.floor(Math.log(bytes) / Math.log(k))

    return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
}

// Demo code
document.body.innerHTML += `<input type="text" oninput="document.querySelector('p').innerHTML=formatBytes(this.value)" value="1000"><p>1000 Bytes</p>`
Expandir fragmento

Versión minimizada (por la comunidad de StackOverflow, minimizada por JSCompress )

function formatBytes(a,b=2){if(!+a)return"0 Bytes";const c=0>b?0:b,d=Math.floor(Math.log(a)/Math.log(1024));return`${parseFloat((a/Math.pow(1024,d)).toFixed(c))} ${["Bytes","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"][d]}`}

Uso:

// formatBytes(bytes, decimals)

formatBytes(1024)       // 1 KiB
formatBytes('1024')     // 1 KiB
formatBytes(1234)       // 1.21 KiB
formatBytes(1234, 3)    // 1.205 KiB
formatBytes(0)          // 0 Bytes
formatBytes('0')        // 0 Bytes

PD: cambia k = 1000o sizes = ["..."]como quieras ( bits o bytes )

l2aelba avatar Sep 06 '2013 05:09 l2aelba

Esta solución incluye un punto decimal y un dígito de décimas si presenta menos de diez de KB o unidades mayores.

const units = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
   
function niceBytes(x){

  let l = 0, n = parseInt(x, 10) || 0;

  while(n >= 1024 && ++l){
      n = n/1024;
  }
  
  return(n.toFixed(n < 10 && l > 0 ? 1 : 0) + ' ' + units[l]);
}

Resultados:

niceBytes(7)                   // 7 bytes
niceBytes(435)                 // 435 bytes
niceBytes(3398)                // 3.3 KiB
niceBytes(490398)              // 479 KiB
niceBytes(6544528)             // 6.2 MiB
niceBytes(23483023)            // 22 MiB
niceBytes(3984578493)          // 3.7 GiB
niceBytes(30498505889)         // 28 GiB
niceBytes(9485039485039445)    // 8.4 PiB

Nota: Utilice las abreviaturas "Kib", etc. cuando utilice la base 1024, porque "KB", etc. en realidad se refiere a la base 1000. Si desea calcular el valor en base 1000, simplemente reemplace 1024 con 1000 en esta función. y utilice las unidades apropiadas (kB, MB, etc.)

Faust avatar Oct 06 '2016 22:10 Faust
function formatBytes(bytes) {
    var marker = 1024; // Change to 1000 if required
    var decimal = 3; // Change as required
    var kiloBytes = marker; // One Kilobyte is 1024 bytes
    var megaBytes = marker * marker; // One MB is 1024 KB
    var gigaBytes = marker * marker * marker; // One GB is 1024 MB
  
    // return bytes if less than a KB
    if(bytes < kiloBytes) return bytes + " Bytes";
    // return KB if less than a MB
    else if(bytes < megaBytes) return(bytes / kiloBytes).toFixed(decimal) + " KB";
    // return MB if less than a GB
    else if(bytes < gigaBytes) return(bytes / megaBytes).toFixed(decimal) + " MB";
    // return GB if less than a TB
    else return(bytes / gigaBytes).toFixed(decimal) + " GB";
}
Jayram avatar May 13 '2014 07:05 Jayram

Aquí hay una sola línea:

val => ['Bytes','Kb','Mb','Gb','Tb'][Math.floor(Math.log2(val)/10)]

O incluso:

v => 'BKMGT'[~~(Math.log2(v)/10)]

Con cuenta:

function shortenBytes(n) {
    const k = n > 0 ? Math.floor((Math.log2(n)/10)) : 0;
    const rank = (k > 0 ? 'KMGT'[k - 1] : '') + 'b';
    const count = Math.floor(n / Math.pow(1024, k));
    return count + rank;
}
iDaN5x avatar Feb 23 '2017 06:02 iDaN5x

Hay dos formas reales de representar tamaños en relación con bytes: unidades SI (10^3) ​​o unidades IEC (2^10). También existe JEDEC pero su método es ambiguo y confuso. Noté que los otros ejemplos tienen errores como usar KB en lugar de kB para representar un kilobyte, así que decidí escribir una función que resolverá cada uno de estos casos usando el rango de unidades de medida actualmente aceptadas.

Hay un bit de formato al final que hará que el número se vea un poco mejor (al menos en mi opinión). Siéntete libre de eliminar ese formato si no se adapta a tu propósito.

Disfrutar.

// pBytes: the size in bytes to be converted.
// pUnits: 'si'|'iec' si units means the order of magnitude is 10^3, iec uses 2^10

function prettyNumber(pBytes, pUnits) {
    // Handle some special cases
    if(pBytes == 0) return '0 Bytes';
    if(pBytes == 1) return '1 Byte';
    if(pBytes == -1) return '-1 Byte';

    var bytes = Math.abs(pBytes)
    if(pUnits && pUnits.toLowerCase() && pUnits.toLowerCase() == 'si') {
        // SI units use the Metric representation based on 10^3 as a order of magnitude
        var orderOfMagnitude = Math.pow(10, 3);
        var abbreviations = ['Bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    } else {
        // IEC units use 2^10 as an order of magnitude
        var orderOfMagnitude = Math.pow(2, 10);
        var abbreviations = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
    }
    var i = Math.floor(Math.log(bytes) / Math.log(orderOfMagnitude));
    var result = (bytes / Math.pow(orderOfMagnitude, i));

    // This will get the sign right
    if(pBytes < 0) {
        result *= -1;
    }

    // This bit here is purely for show. it drops the percision on numbers greater than 100 before the units.
    // it also always shows the full number of bytes if bytes is the unit.
    if(result >= 99.995 || i==0) {
        return result.toFixed(0) + ' ' + abbreviations[i];
    } else {
        return result.toFixed(2) + ' ' + abbreviations[i];
    }
}
Brennan T avatar Sep 03 '2014 18:09 Brennan T