我使用这个函数将文件大小(以字节为单位)转换为人类可读的文件大小:

零二线函数 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"

其他回答

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 "

这是我写的一个:

/** * 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

@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]}`;
};

这里有很多很棒的答案。但是,如果您正在寻找一种非常简单的方法,并且不介意使用流行的库,那么filesize https://www.npmjs.com/package/filesize就是一个很好的解决方案

它有很多选项,用法也很简单。

filesize(265318); // "259.1 KB"

从他们优秀的例子中

对于那些使用Angular的人来说,有一个名为Angular -pipes的包,它有一个管道:

File

import { BytesPipe } from 'angular-pipes';

使用

{{ 150 | bytes }} <!-- 150 B -->
{{ 1024 | bytes }} <!-- 1 KB -->
{{ 1048576 | bytes }} <!-- 1 MB -->
{{ 1024 | bytes: 0 : 'KB' }} <!-- 1 MB -->
{{ 1073741824 | bytes }} <!-- 1 GB -->
{{ 1099511627776 | bytes }} <!-- 1 TB -->
{{ 1073741824 | bytes : 0 : 'B' : 'MB' }} <!-- 1024 MB -->

链接到文档。