文件大小获取到的是以B(字节)为单位,在页面上显示时,需要先格式化一下。一开始用的是if..else..,幸好实际中文件大小顶多达到T级,进行4次判断就可以了。但这终究不是个好方法,琢磨着可以循环来实现。
先了解下进制间的转换规则:
1 B = 2 10*0 B
1 K = 210 * 1 B
1 M = 210 K = 210*2 B
1 G = 210 M = 220 K =210*3 B
1 T = 210 G= 220 M = 230 K = 210*4 B
这样一来,实现起来就很简单了:
function FormatSize (fileSize) {
var arrUnit = ["B", "K", "M", "G", "T", "P"],
baseStep = 1024,
unitCount = arrUnit.length,
unitIndex = 0;
while(fileSize >= baseStep && unitIndex < unitCount - 1){
unitIndex++;
fileSize /= baseStep;
}
fileSize = fileSize.toFixed(2);
return fileSize + " " + arrUnit[unitIndex];
}
后来看到花儿同学的实现,禁不住想要再赞下,巧妙地运用了对数函数求解,关键代码仅有一句话:
[var size =roundFun(srcsize/Math.pow(1024,(index=Math.floor(Math.log(srcsize)/Math.log(1024)))),2); ]
(Math.log – 以 自然数 e 为底的对数 ln)
一步一步分解如下:
FSize = (210)N B =1024N B
N = log1024 FSize = ln FSize / ln 1024
N = Floor(N) (向下取整)
size = FSize / Power(1024, N)
既然是用对数,难道没有以2为底的对数么?
查了下Math函数,是有log2 方法的,改进下: FSize = 210*N B; N = log2 FSize / 10; …
最终的实现方法是:function FormatSize (fileSize) {
var arrUnit = ["B", "K","M", "G", "T", "P"];
var powerIndex = Math.log2(fileSize) / 10;
powerIndex = Math.floor(powerIndex);
// index should in the unit range!
var len = arrUnit.length;
powerIndex = powerIndex < len ? powerIndex : len - 1;
var sizeFormatted = fileSize / Math.pow(2, powerIndex * 10
sizeFormatted = sizeFormatted.toFixed(2);
return sizeFormatted + " " + arrUnit[powerIndex];
}