Korrekt måte å konvertere størrelse i bytes til KB, MB, GB i JavaScript
Jeg fikk denne koden for å konvertere størrelse i bytes via PHP.
Nå vil jeg konvertere disse størrelsene til menneskelig lesbare størrelser ved hjelp av JavaScript. Jeg prøvde å konvertere denne koden til JavaScript, som ser slik ut:
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;
}
Er dette den riktige måten å gjøre dette på? Finnes det en enklere måte?
Svar #1
Fra dette: (kilde)
Uminifisert og ES6'et: (av fellesskapet)
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>`Minifisert versjon (av StackOverflows fellesskap, minifisert av 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]}`}
Bruk:
// 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
PS: Endre k=1000 eller sizes=["..."] som du vil (biter eller bytes)
Svar #2
Denne løsningen inkluderer et desimaltegn og et tidels-siffer hvis den presenterer mindre enn ti KB eller større enheter
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]);
}
Resultater :
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
Merk: Bruk forkortelsene "Kib" osv. når du bruker base 1024, fordi "KB" osv. faktisk refererer til base 1000. Hvis du ønsker å beregne verdien til base 1000, erstatt bare 1024 med 1000 i denne funksjonen, og bruk de riktige enhetene (kB, MB, osv.)
Svar #3
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";
}
Svar #4
Her er en en-liner:
val => ['Bytes','Kb','Mb','Gb','Tb'][Math.floor(Math.log2(val)/10)]
Eller til og med:
v => 'BKMGT'[~~(Math.log2(v)/10)]
Med telling:
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;
}
Svar #5
Det finnes 2 ekte måter å representere størrelser relatert til byte på, de er SI-enheter (10^3) eller IEC-enheter (2^10). Det finnes også JEDEC, men deres metode er tvetydig og forvirrende. Jeg la merke til at de andre eksemplene har feil, for eksempel å bruke KB i stedet for kB for å representere en kilobyte, så jeg bestemte meg for å skrive en funksjon som vil løse hver av disse tilfellene ved å bruke området av nåværende godkjente måleenheter.
Det er et formateringsbit på slutten som vil få tallet til å se litt bedre ut (i det minste for mitt øye), føl deg fri til å fjerne den formateringen hvis det ikke passer ditt formål.
Kos deg.
// 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];
}
}
Svar #6
Du kan bruke filesizejs-biblioteket.
