我使用这个函数将文件大小(以字节为单位)转换为人类可读的文件大小:
零二线函数
var i = -1;
var byteUnits =[英国‘计划生育’‘兆’,‘和合’,‘PB’‘EB”、“ZB’,‘YB];
do {
fileSizeInBytes /= 1024;
我+;
while (fileSizeInBytes > 1024)
数学归来。max(fileSizeInBytes, 0.1)。toFixed(1) + byteUnits[i];
的
控制台日志(getReadableFileSizeString (1551859712);//输出是“1.4 GB”
然而,这似乎不是百分之百准确的。例如:
getReadableFileSizeString(1551859712); // output is "1.4 GB"
不应该是“1.5 GB”吗?除以1024似乎失去了精度。是我完全误解了什么,还是有更好的办法?
@Andrew V的typescript版本带有新的“模板文字类型”
export const humanFileSize = (bytes: number): `${number} ${'B' | 'KB' | 'MB' | 'GB' | 'TB'}` => {
const index = Math.floor(Math.log(bytes) / Math.log(1024));
return `${Number((bytes / Math.pow(1024, index)).toFixed(2)) * 1} ${(['B', 'KB', 'MB', 'GB', 'TB'] as const)[index]}`;
};
一个简单而简短的“Pretty Bytes”函数,用于SI系统,没有不必要的分数舍入。
事实上,因为数字大小应该是人类可读的,“千分之一”的显示不再是人类的。
小数点后的位数默认为2,但可以在调用函数时修改其他值。常见的大多数显示是默认的小数点后2位。
代码很短,并使用了数字字符串三胞胎的方法。
// Simple Pretty Bytes with SI system
// Without fraction rounding
function numberPrettyBytesSI(Num=0, dec=2){
if (Num<1000) return Num+" Bytes";
Num =("0".repeat((Num+="").length*2%3)+Num).match(/.{3}/g);
return Number(Num[0])+"."+Num[1].substring(0,dec)+" "+" kMGTPEZY"[Num.length]+"B";
}
console.log(numberPrettyBytesSI(0));
console.log(numberPrettyBytesSI(500));
console.log(numberPrettyBytesSI(1000));
console.log(numberPrettyBytesSI(15000));
console.log(numberPrettyBytesSI(12345));
console.log(numberPrettyBytesSI(123456));
console.log(numberPrettyBytesSI(1234567));
console.log(numberPrettyBytesSI(12345678));
我发现@cocco的回答很有趣,但有以下问题:
不要修改原生类型或您不拥有的类型
为人类编写干净、可读的代码,让最小化器为机器优化代码
(对TypeScript用户的奖励)不能很好地使用TypeScript
打字稿:
/**
* Describes manner by which a quantity of bytes will be formatted.
*/
enum ByteFormat {
/**
* Use Base 10 (1 kB = 1000 bytes). Recommended for sizes of files on disk, disk sizes, bandwidth.
*/
SI = 0,
/**
* Use Base 2 (1 KiB = 1024 bytes). Recommended for RAM size, size of files on disk.
*/
IEC = 1
}
/**
* Returns a human-readable representation of a quantity of bytes in the most reasonable unit of magnitude.
* @example
* formatBytes(0) // returns "0 bytes"
* formatBytes(1) // returns "1 byte"
* formatBytes(1024, ByteFormat.IEC) // returns "1 KiB"
* formatBytes(1024, ByteFormat.SI) // returns "1.02 kB"
* @param size The size in bytes.
* @param format Format using SI (Base 10) or IEC (Base 2). Defaults to SI.
* @returns A string describing the bytes in the most reasonable unit of magnitude.
*/
function formatBytes(
value: number,
format: ByteFormat = ByteFormat.SI
) {
const [multiple, k, suffix] = (format === ByteFormat.SI
? [1000, 'k', 'B']
: [1024, 'K', 'iB']) as [number, string, string]
// tslint:disable-next-line: no-bitwise
const exp = (Math.log(value) / Math.log(multiple)) | 0
// or, if you'd prefer not to use bitwise expressions or disabling tslint rules, remove the line above and use the following:
// const exp = value === 0 ? 0 : Math.floor(Math.log(value) / Math.log(multiple))
const size = Number((value / Math.pow(multiple, exp)).toFixed(2))
return (
size +
' ' +
(exp
? (k + 'MGTPEZY')[exp - 1] + suffix
: 'byte' + (size !== 1 ? 's' : ''))
)
}
// example
[0, 1, 1024, Math.pow(1024, 2), Math.floor(Math.pow(1024, 2) * 2.34), Math.pow(1024, 3), Math.floor(Math.pow(1024, 3) * 892.2)].forEach(size => {
console.log('Bytes: ' + size)
console.log('SI size: ' + formatBytes(size))
console.log('IEC size: ' + formatBytes(size, 1) + '\n')
});
基于cocco的答案,但略有淡化(老实说,那些我觉得舒服的被保留/添加),不显示后面的0,但仍然支持0,希望对其他人有用:
函数fileSizeSI(size) {
var e = (Math.log(size) / Math.log(1e3)) | 0;
return +(size / Math.)战俘(1 e3, e)) .toFixed (2 ) + ' ' + (' kMGTPEZY [e - 1 ] || '') + ' B”;
}
/ /测试:
文档。write([0, 23, 4322, 324232132, 22e9, 64.22e12, 76.22e15, 64.66e18, 77.11e21, 22e24].map(fileSizeSI).join('<br>'));