J'ai obtenu ce code pour convertir la taille en octets via PHP.
Maintenant, je veux convertir ces tailles en lisibles en utilisant JavaScript. J'ai essayé de convertir ce code en JavaScript, qui ressemble à ceci:
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;
}
Est-ce la bonne façon de faire cela? Y a-t-il un moyen plus facile?
À partir de ceci: ( source )
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes == 0) return '0 Byte';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
};
Note: Ceci est le code original. Veuillez utiliser la version corrigée ci-dessous. Aliceljm n'active plus son code copié
Now, Version corrigée: _ (par la communauté de Stackoverflow, + Minifié par JSCompress )
function formatBytes(a,b){if(0==a)return"0 Bytes";var c=1024,d=b||2,e=["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],f=Math.floor(Math.log(a)/Math.log(c));return parseFloat((a/Math.pow(c,f)).toFixed(d))+" "+e[f]}
Utilisation:
// formatBytes(bytes,decimals)
formatBytes(1024); // 1 KB
formatBytes('1024'); // 1 KB
formatBytes(1234); // 1.21 KB
formatBytes(1234, 3); // 1.205 KB
Démo/source:
function formatBytes(bytes,decimals) {
if(bytes == 0) return '0 Bytes';
var k = 1024,
dm = decimals <= 0 ? 0 : decimals || 2,
sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
// ** Demo code **
var p = document.querySelector('p'),
input = document.querySelector('input');
function setText(v){
p.innerHTML = formatBytes(v);
}
// bind 'input' event
input.addEventListener('input', function(){
setText( this.value )
})
// set initial text
setText(input.value);
<input type="text" value="1000">
<p></p>
PS: changez k = 1000
ou sizes = ["..."]
comme vous le souhaitez (bits ou octets)}
function formatBytes(bytes) {
if(bytes < 1024) return bytes + " Bytes";
else if(bytes < 1048576) return(bytes / 1024).toFixed(3) + " KB";
else if(bytes < 1073741824) return(bytes / 1048576).toFixed(3) + " MB";
else return(bytes / 1073741824).toFixed(3) + " GB";
};
const units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
function niceBytes(x){
let l = 0, n = parseInt(x, 10) || 0;
while(n >= 1024 && ++l)
n = n/1024;
//include a decimal point and a tenths-place digit if presenting
//less than ten of KB or greater units
return(n.toFixed(n < 10 && l > 0 ? 1 : 0) + ' ' + units[l]);
}
Résultats:
niceBytes(435) // 435 bytes
niceBytes(3398) // 3.3 KB
niceBytes(490398) // 479 KB
niceBytes(6544528) // 6.2 MB
niceBytes(23483023) // 22 MB
niceBytes(3984578493) // 3.7 GB
niceBytes(30498505889) // 28 GB
niceBytes(9485039485039445) // 8.4 PB
Il existe deux manières réelles de représenter des tailles liées à des octets: ce sont des unités SI (10 ^ 3) ou des unités IEC (2 ^ 10). Il y a aussi JEDEC mais leur méthode est ambiguë et déroutante. J'ai remarqué que les autres exemples comportent des erreurs telles que l'utilisation de KB au lieu de kB pour représenter un kilo-octet. J'ai donc décidé d'écrire une fonction qui résoudra chacun de ces cas en utilisant la plage des unités de mesure actuellement acceptées.
Il y a un bit de formatage à la fin qui donnera au numéro un aspect un peu meilleur (du moins à mes yeux), n'hésitez pas à supprimer ce formatage s'il ne vous convient pas.
Prendre plaisir.
// 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];
}
}
Vous pouvez utiliser la bibliothèque filesizejs .
Utiliser une opération bit à bit serait une meilleure solution. Essaye ça
function formatSizeUnits(bytes)
{
if ( ( bytes >> 30 ) & 0x3FF )
bytes = ( bytes >>> 30 ) + '.' + ( bytes & (3*0x3FF )) + 'GB' ;
else if ( ( bytes >> 20 ) & 0x3FF )
bytes = ( bytes >>> 20 ) + '.' + ( bytes & (2*0x3FF ) ) + 'MB' ;
else if ( ( bytes >> 10 ) & 0x3FF )
bytes = ( bytes >>> 10 ) + '.' + ( bytes & (0x3FF ) ) + 'KB' ;
else if ( ( bytes >> 1 ) & 0x3FF )
bytes = ( bytes >>> 1 ) + 'Bytes' ;
else
bytes = bytes + 'Byte' ;
return bytes ;
}
Selon la réponse de Aliceljm , j'ai enlevé 0 après le signe décimal:
function formatBytes(bytes, decimals) {
if(bytes== 0)
{
return "0 Byte";
}
var k = 1024; //Or 1 kilo = 1000
var sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB"];
var i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)) + " " + sizes[i];
}
function bytesToSize(bytes) {
var sizes = ['B', 'K', 'M', 'G', 'T', 'P'];
for (var i = 0; i < sizes.length; i++) {
if (bytes <= 1024) {
return bytes + ' ' + sizes[i];
} else {
bytes = parseFloat(bytes / 1024).toFixed(2)
}
}
return bytes + ' P';
}
console.log(bytesToSize(234));
console.log(bytesToSize(2043));
console.log(bytesToSize(20433242));
console.log(bytesToSize(2043324243));
console.log(bytesToSize(2043324268233));
console.log(bytesToSize(2043324268233343));
A l'origine, j'avais utilisé la réponse de @Aliceljm pour un projet de téléchargement de fichier sur lequel je travaillais, mais j'ai récemment rencontré un problème dans lequel un fichier était 0.98kb
mais en cours de lecture en tant que 1.02mb
. Voici le code mis à jour que j'utilise maintenant.
function formatBytes(bytes){
var kb = 1024;
var ndx = Math.floor( Math.log(bytes) / Math.log(kb) );
var fileSizeTypes = ["bytes", "kb", "mb", "gb", "tb", "pb", "eb", "zb", "yb"];
return {
size: +(bytes / kb / kb).toFixed(2),
type: fileSizeTypes[ndx]
};
}
Ce qui précède serait alors appelé après l’ajout d’un fichier,
// In this case `file.size` equals `26060275`
formatBytes(file.size);
// returns `{ size: 24.85, type: "mb" }`
Certes, Windows lit le fichier comme étant 24.8mb
mais la précision supplémentaire me convient.
Je mets à jour @Aliceljm répondre ici. Étant donné que la décimale est importante pour les nombres à 1,2 chiffre, j’arrondis la première décimale et conserve la première décimale. Pour un nombre à 3 chiffres, je vais arrondir la place des unités et ignorer toutes les décimales.
getMultiplers : function(bytes){
var unit = 1000 ;
if (bytes < unit) return bytes ;
var exp = Math.floor(Math.log(bytes) / Math.log(unit));
var pre = "kMGTPE".charAt(exp-1);
var result = bytes / Math.pow(unit, exp);
if(result/100 < 1)
return (Math.round( result * 10 ) / 10) +pre;
else
return Math.round(result) + pre;
}
Cette solution s'appuie sur les solutions précédentes, mais prend en compte les unités métriques et binaires:
function formatBytes(bytes, decimals, binaryUnits) {
if(bytes == 0) {
return '0 Bytes';
}
var unitMultiple = (binaryUnits) ? 1024 : 1000;
var unitNames = (unitMultiple === 1024) ? // 1000 bytes in 1 Kilobyte (KB) or 1024 bytes for the binary version (KiB)
['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']:
['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
var unitChanges = Math.floor(Math.log(bytes) / Math.log(unitMultiple));
return parseFloat((bytes / Math.pow(unitMultiple, unitChanges)).toFixed(decimals || 0)) + ' ' + unitNames[unitChanges];
}
Exemples:
formatBytes(293489203947847, 1); // 293.5 TB
formatBytes(1234, 0); // 1 KB
formatBytes(4534634523453678343456, 2); // 4.53 ZB
formatBytes(4534634523453678343456, 2, true)); // 3.84 ZiB
formatBytes(4566744, 1); // 4.6 MB
formatBytes(534, 0); // 534 Bytes
formatBytes(273403407, 0); // 273 MB
var SIZES = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
function formatBytes(bytes, decimals) {
for(var i = 0, r = bytes, b = 1024; r > b; i++) r /= b;
return `${parseFloat(r.toFixed(decimals))} ${SIZES[i]}`;
}
Voici comment afficher un octet à un humain:
function bytesToHuman(bytes, decimals = 2) {
// https://en.wikipedia.org/wiki/Orders_of_magnitude_(data)
const units = ["bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"]; // etc
let i = 0;
let h = 0;
let c = 1 / 1023; // change it to 1024 and see the diff
for (; h < c && i < units.length; i++) {
if ((h = Math.pow(1024, i) / bytes) >= c) {
break;
}
}
// remove toFixed and let `locale` controls formatting
return (1 / h).toFixed(decimals).toLocaleString() + " " + units[i];
}
// test
for (let i = 0; i < 9; i++) {
let val = i * Math.pow(10, i);
console.log(val.toLocaleString() + " bytes is the same as " + bytesToHuman(val));
}
// let's fool around
console.log(bytesToHuman(1023));
console.log(bytesToHuman(1024));
console.log(bytesToHuman(1025));