javascript - soljson - smart contracts ethereum
Conversión de tamaño de archivo en bytes a una cadena legible por humanos (11)
Estoy usando esta función para convertir un tamaño de archivo en bytes a un tamaño de archivo legible por humanos:
function getReadableFileSizeString(fileSizeInBytes) {
var i = -1;
var byteUnits = ['' kB'', '' MB'', '' GB'', '' TB'', ''PB'', ''EB'', ''ZB'', ''YB''];
do {
fileSizeInBytes = fileSizeInBytes / 1024;
i++;
} while (fileSizeInBytes > 1024);
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
};
Sin embargo, parece que esto no es 100% exacto. Por ejemplo:
getReadableFileSizeString(1551859712); // output is "1.4 GB"
¿No debería ser esto "1.5 GB"
? Parece que la división de 1024 está perdiendo precisión. ¿Estoy totalmente mal entendiendo algo o hay una mejor manera de hacerlo?
Aquí está el mío: funciona también para archivos realmente grandes -_-
function formatFileSize(size)
{
var sizes = ['' Bytes'', '' KB'', '' MB'', '' GB'', '' TB'', '' PB'', '' EB'', '' ZB'', '' YB''];
for (var i = 1; i < sizes.length; i++)
{
if (size < Math.pow(1024, i)) return (Math.round((size/Math.pow(1024, i-1))*100)/100) + sizes[i-1];
}
return size;
}
Aquí hay uno que escribí:
function humanFileSize(bytes, si) {
var thresh = si ? 1000 : 1024;
if(Math.abs(bytes) < thresh) {
return bytes + '' B'';
}
var units = si
? [''kB'',''MB'',''GB'',''TB'',''PB'',''EB'',''ZB'',''YB'']
: [''KiB'',''MiB'',''GiB'',''TiB'',''PiB'',''EiB'',''ZiB'',''YiB''];
var u = -1;
do {
bytes /= thresh;
++u;
} while(Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1)+'' ''+units[u];
}
p.ej
humanFileSize(5000,true)
> "5.0 kB"
humanFileSize(5000,false)
> "4.9 KiB"
humanFileSize(-10000000000000000000000000000)
> "-8271.8 YiB"
Basándonos en la idea de , aquí hay un ejemplo menos compacto, pero afortunadamente más completo.
<!DOCTYPE html>
<html>
<head>
<title>File info</title>
<script>
<!--
function fileSize(bytes) {
var exp = Math.log(bytes) / Math.log(1024) | 0;
var result = (bytes / Math.pow(1024, exp)).toFixed(2);
return result + '' '' + (exp == 0 ? ''bytes'': ''KMGTPEZY''[exp - 1] + ''B'');
}
function info(input) {
input.nextElementSibling.textContent = fileSize(input.files[0].size);
}
-->
</script>
</head>
<body>
<label for="upload-file"> File: </label>
<input id="upload-file" type="file" onchange="info(this)">
<div></div>
</body>
</html>
Basado en la respuesta de Cocco pero levemente desequilibrado (honestamente, los que me gustaban se mantienen / agregan) y no muestra ceros al final, pero aún admite 0, espero ser útil para otros:
function fileSizeSI(size) {
var e = (Math.log(size) / Math.log(1e3)) | 0;
return +(size / Math.pow(1e3, e)).toFixed(2) + '' '' + (''kMGTPEZY''[e - 1] || '''') + ''B'';
}
// test:
document.write([0, 23, 4322, 324232132, 22e9, 64.22e12, 76.22e15, 64.66e18, 77.11e21, 22e24].map(fileSizeSI).join(''<br>''));
Depende de si desea utilizar la convención binaria o decimal.
La RAM, por ejemplo, siempre se mide en binario, por lo que expresar 1551859712 como ~ 1.4GiB sería correcto.
Por otro lado, a los fabricantes de discos duros les gusta usar decimal, por lo que lo llamarían ~ 1.6GB.
Y para ser confuso, los disquetes usan una mezcla de los dos sistemas: sus 1MB son en realidad 1024000 bytes.
Otra realización del cálculo
function humanFileSize(size) {
var i = Math.floor( Math.log(size) / Math.log(1024) );
return ( size / Math.pow(1024, i) ).toFixed(2) * 1 + '' '' + [''B'', ''kB'', ''MB'', ''GB'', ''TB''][i];
};
Otro ejemplo similar a los aquí
function fileSize(b) {
var u = 0, s=1024;
while (b >= s || -b >= s) {
b /= s;
u++;
}
return (u ? b.toFixed(1) + '' '' : b) + '' KMGTPEZY''[u] + ''B'';
}
Mide un desempeño insignificantemente mejor que otros con características similares.
Solución como componente ReactJS
Bytes = React.createClass({
formatBytes() {
var i = Math.floor(Math.log(this.props.bytes) / Math.log(1024));
return !this.props.bytes && ''0 Bytes'' || (this.props.bytes / Math.pow(1024, i)).toFixed(2) + " " + [''Bytes'', ''KB'', ''MB'', ''GB'', ''TB'', ''PB'', ''EB'', ''ZB'', ''YB''][i]
},
render () {
return (
<span>{ this.formatBytes() }</span>
);
}
});
ACTUALIZACIÓN Para aquellos que usan es6 aquí hay una versión sin estado de este mismo componente
const sufixes = [''Bytes'', ''KB'', ''MB'', ''GB'', ''TB'', ''PB'', ''EB'', ''ZB'', ''YB''];
const getBytes = (bytes) => {
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return !bytes && ''0 Bytes'' || (bytes / Math.pow(1024, i)).toFixed(2) + " " + sufixes[i];
};
const Bytes = ({ bytes }) => (<span>{ getBytes(bytes) }</span>);
Bytes.propTypes = {
bytes: React.PropTypes.number,
};
Aquí hay un prototipo para convertir un número en una cadena legible respetando los nuevos estándares internacionales.
Hay dos formas de representar números grandes: puede mostrarlos en múltiplos de 1000 = 10 3 (base 10) o 1024 = 2 10 (base 2). Si divide por 1000, probablemente use los nombres de prefijo SI, si divide por 1024, probablemente use los nombres de prefijo IEC. El problema comienza con la división por 1024. Muchas aplicaciones usan los nombres de prefijo SI para ello y algunas usan los nombres de prefijo IEC. La situación actual es un desastre. Si ve nombres de prefijos SI, no sabe si el número está dividido entre 1000 o 1024
https://wiki.ubuntu.com/UnitsPolicy
http://en.wikipedia.org/wiki/Template:Quantities_of_bytes
Object.defineProperty(Number.prototype,''fileSize'',{value:function(a,b,c,d){
return (a=a?[1e3,''k'',''B'']:[1024,''K'',''iB''],b=Math,c=b.log,
d=c(this)/c(a[0])|0,this/b.pow(a[0],d)).toFixed(2)
+'' ''+(d?(a[1]+''MGTPEZY'')[--d]+a[2]:''Bytes'');
},writable:false,enumerable:false});
Esta función no contiene ningún loop
, por lo que es probablemente más rápido que otras funciones.
Uso:
Prefijo IEC
console.log((186457865).fileSize()); // default IEC (power 1024)
//177.82 MiB
//KiB,MiB,GiB,TiB,PiB,EiB,ZiB,YiB
Prefijo SI
console.log((186457865).fileSize(1)); //1,true for SI (power 1000)
//186.46 MB
//kB,MB,GB,TB,PB,EB,ZB,YB
configuro el IEC como predeterminado porque siempre usé el modo binario para calcular el tamaño de un archivo ... usando el poder de 1024
Si solo quiere uno de ellos en una función breve de diseño:
SI
function fileSizeSI(a,b,c,d,e){
return (b=Math,c=b.log,d=1e3,e=c(a)/c(d)|0,a/b.pow(d,e)).toFixed(2)
+'' ''+(e?''kMGTPEZY''[--e]+''B'':''Bytes'')
}
//kB,MB,GB,TB,PB,EB,ZB,YB
IEC
function fileSizeIEC(a,b,c,d,e){
return (b=Math,c=b.log,d=1024,e=c(a)/c(d)|0,a/b.pow(d,e)).toFixed(2)
+'' ''+(e?''KMGTPEZY''[--e]+''iB'':''Bytes'')
}
//KiB,MiB,GiB,TiB,PiB,EiB,ZiB,YiB
Uso:
console.log(fileSizeIEC(7412834521));
si tiene alguna pregunta sobre las funciones solo pregunte
1551859712 / 1024 = 1515488
1515488 / 1024 = 1479.96875
1479.96875 / 1024 = 1.44528198242188
Tu solución es correcta Lo importante es darse cuenta de que para pasar de 1551859712
a 1.5
, debe dividir entre 1000, pero los bytes se cuentan en bloques binarios a decimales de 1024, por lo que el valor de Gigabyte es menor.
sizeOf = function (bytes) {
if (bytes == 0) { return "0.00 B"; }
var e = Math.floor(Math.log(bytes) / Math.log(1024));
return (bytes/Math.pow(1024, e)).toFixed(2)+'' ''+'' KMGTP''.charAt(e)+''B'';
}
sizeOf (2054110009);
// => "1.91 GB"sizeOf (7054110);
// => "6.73 MB"sizeOf ((3 * 1024 * 1024));
// => "3.00 MB"