Forma correcta de convertir el tamaño en bytes a KB, MB, GB en JavaScript
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?
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>`
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 = 1000
o sizes = ["..."]
como quieras ( bits o bytes )
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.)
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";
}
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;
}
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];
}
}