private static Map<Long, String> DATA_MAP_BINARY_PREFIXES = new HashMap<Long, String>() {{ put(0L, "0 Bytes"); put(1023L, "1023 Bytes"); put(1024L, "1 KiB"); put(12_345L, "12.06 KiB"); put(10_123_456L, "9.65 MiB"); put(10_123_456_798L, "9.43 GiB"); put(1_777_777_777_777_777_777L, "1.54 EiB"); }};
Given a Byte value in Java, the task is to convert this byte value to string type. One method is to create a string variable and then append the byte value to the string variable with the help of + operator. This will directly convert the byte value to a string and add it in the string variable.
Here's one I wrote:
/**
* Format bytes as human-readable text.
*
* @param bytes Number of bytes.
* @param si True to use metric (SI) units, aka powers of 1000. False to use
* binary (IEC), aka powers of 1024.
* @param dp Number of decimal places to display.
*
* @return Formatted string.
*/
function humanFileSize(bytes, si=false, dp=1) {
const thresh = si ? 1000 : 1024;
if (Math.abs(bytes) < thresh) {
return bytes + ' B';
}
const units = si
? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
let u = -1;
const r = 10**dp;
do {
bytes /= thresh;
++u;
} while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);
return bytes.toFixed(dp) + ' ' + units[u];
}
console.log(humanFileSize(1551859712)) // 1.4 GiB
console.log(humanFileSize(5000, true)) // 5.0 kB
console.log(humanFileSize(5000, false)) // 4.9 KiB
console.log(humanFileSize(-10000000000000000000000000000)) // -8271.8 YiB
console.log(humanFileSize(999949, true)) // 999.9 kB
console.log(humanFileSize(999950, true)) // 1.0 MB
console.log(humanFileSize(999950, true, 2)) // 999.95 kB
console.log(humanFileSize(999500, true, 0)) // 1 MB
Another embodiment of the calculation
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];
};
It depends on whether you want to use the binary or decimal convention.
RAM, for instance, is always measured in binary, so to express 1551859712 as ~1.4GiB would be correct.
On the other hand, hard disk manufacturers like to use decimal, so they would call it ~1.6GB.
And just to be confusing, floppy disks use a mixture of the two systems - their 1MB is actually 1024000 bytes.
Here is a prototype to convert a number to a readable string respecting the new international standards.
There are two ways to represent big numbers: You could either display them in multiples of 1000 = 10 3 (base 10) or 1024 = 2 10 (base 2). If you divide by 1000, you probably use the SI prefix names, if you divide by 1024, you probably use the IEC prefix names. The problem starts with dividing by 1024. Many applications use the SI prefix names for it and some use the IEC prefix names. The current situation is a mess. If you see SI prefix names you do not know whether the number is divided by 1000 or 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});
This function contains no loop
, and so it's probably faster than some other functions.
Usage:
IEC prefix
console.log((186457865).fileSize()); // default IEC (power 1024)
//177.82 MiB
//KiB,MiB,GiB,TiB,PiB,EiB,ZiB,YiB
SI prefix
console.log((186457865).fileSize(1)); //1,true for SI (power 1000)
//186.46 MB
//kB,MB,GB,TB,PB,EB,ZB,YB
i set the IEC as default because i always used binary mode to calculate the size of a file... using the power of 1024
If you just want one of them in a short oneliner function:
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
Usage:
console.log(fileSizeIEC(7412834521));
if you have some questions about the functions just ask
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"
Solution as ReactJS Component
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>
);
}
});
UPDATE For those using es6 here is a stateless version of this same component
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,
};
Based on cocco's idea, here's a less compact -but hopefully more comprehensive- example.
<!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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With