我使用这个函数将文件大小(以字节为单位)转换为人类可读的文件大小:
零二线函数
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似乎失去了精度。是我完全误解了什么,还是有更好的办法?
我想要“文件管理器”行为(例如,Windows资源管理器),其中小数位数与数字大小成比例。似乎没有其他答案是这样的。
function humanFileSize(size) {
if (size < 1024) return size + ' B'
let i = Math.floor(Math.log(size) / Math.log(1024))
let num = (size / Math.pow(1024, i))
let round = Math.round(num)
num = round < 10 ? num.toFixed(2) : round < 100 ? num.toFixed(1) : round
return `${num} ${'KMGTPEZY'[i-1]}B`
}
下面是一些例子:
humanFileSize(0) // "0 B"
humanFileSize(1023) // "1023 B"
humanFileSize(1024) // "1.00 KB"
humanFileSize(10240) // "10.0 KB"
humanFileSize(102400) // "100 KB"
humanFileSize(1024000) // "1000 KB"
humanFileSize(12345678) // "11.8 MB"
humanFileSize(1234567890) // "1.15 GB"
我发现@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')
});
@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]}`;
};