I am currently trying to convert this php function to javascript:
function human_filesize($bytes, $decimals = 2) {
$sz = 'BKMGTP';
$factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
}
Here's what I have so Far:
function human_filesiz(bytes){
var decimals = 2;
var sz = 'BKMGTP';
var factor = Math.floor((bytes.length - 1) / 3);
return (bytes / Math.pow(1024, factor));
//return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
}
Im Just struggling with the last line. Any Help Greatly Appreciated.
Did you have a look at: http://programanddesign.com/js/human-readable-file-size-in-javascript/ They have two version of a Javascript solution for Human Readable Filesize:
function fileSize(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];
}
and
function readableFileSize(size) {
var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
var i = 0;
while(size >= 1024) {
size /= 1024;
++i;
}
return size.toFixed(1) + ' ' + units[i];
}
Based on the new international standards:
there are 2 ways now (SI & IEC)... or better 3 including the old one(JEDEC memory standards).
old standard (JEDEC & SI):
kB=1000, KB=1024
MB=1024=1000
GB=1024=1000
as you can see everything is messed up as you don't know if they are using 1024 or 1000 as multipler
https://wiki.ubuntu.com/UnitsPolicy
thats why we have this 2 new standards now:
Decimal (International System of Units [SI])
kB,MB,GB.. = 1000
Binary (International Electrotechnical Commission [IEC])
KiB,MiB,GiB.. = 1024
http://en.wikipedia.org/wiki/Binary_prefix
here are 2 functions i just wrote using shorthand and bitwise to make it fast & short.
function fileSizeSI(a,b,c,d,e){
return (b=Math,c=b.log,d=1000,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
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
fileSizeSI(5768374623);
//5.77 GB
fileSizeIEC(5768374623);
//5.37 GiB
EDIT
And here is a prototype for modern browsers that can handle both
Object.defineProperty(Number.prototype,'fileSize',{value:function(a,b,c,d){
return (a=a=='SI'?[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});
// default(IEC) KiB,MiB,GiB,TiB,PiB,EiB,ZiB,YiB
// (SI) kB,MB,GB,TB,PB,EB,ZB,YB
usage
(1289139173).fileSize(); // default Binary IEC
//1.20 GiB
(1289139173).fileSize('SI'); // Metric SI
//1.29 GB
i always used 1024 to calculate the size ... so i put the new IEC standard as default.
if you have some questions about the functions just ask
The answer by osi is great. If you want to understand what JS can do for your example though, you can take a look at this code which I made work for you:
function human_filesiz(bytes){
var decimals = 2;
var sz = 'BKMGTP';
bytesStr = new String(bytes);
var factor = Math.floor((bytesStr.length - 1) / 3);
// rounding the number in JS:
var number = bytes / Math.pow(1024, factor);
var roundPrecision = Math.pow(10, decimals);
number *= roundPrecision;
var result = Math.round(number, decimals) / roundPrecision;
result = result + sz.substring(factor, 1);
return result;
}
I like cocco's version .
I added rounding and locale conversion for the separators.
Object.defineProperty(Number.prototype, 'toFileSize', {
value: function(a, b, c, d){ return (a=a=='SI'?[1e3,'k','B']:[1024,'K','iB'],b=Math,c=b.log,d=c(this)/c(a[0])|0,+(b.round(this/b.pow(a[0],d)+"e+2")+"e-2")).toLocaleString()+' '+(d?(a[1]+'MGTPEZY')[--d]+a[2]:'Bytes');},
writable: false,
enumerable: false
});
we should stop the loop when size exceeds what we have anticipated in the units array
function toHuman(size) {
var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
var i = 0;
var j = units.length - 1;
while(size >= 1024 && i<j) {
size /= 1024;
++i;
}
return size.toFixed(1) + ' ' + units[i];
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.