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

零二线函数 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似乎失去了精度。是我完全误解了什么,还是有更好的办法?


当前回答

这是我写的一个:

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

其他回答

这是我写的一个:

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

要在投票的解决方案中动态调整小数的数量,将bytes.toFixed(dp)转换为数字,然后再转换为字符串,就像这样:

return Number(bytes.toFixed(dp)).toString() + " " + units[u];

这将显示100 GiB而不是100.00 GiB。 在js中动态引用问题toFixed()

计算的另一个体现

function humanFileSize(size) {
    var i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));
    return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
}

下面是另一个国际化的实现,用TypeScript编写:

const UNITS = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte', 'petabyte']
const BYTES_PER_KB = 1000


/**
 * Format bytes as human-readable text.
 *
 * @param sizeBytes Number of bytes.
 *
 * @return Formatted string.
 */
export function humanFileSize(sizeBytes: number | bigint): string {
    let size = Math.abs(Number(sizeBytes))

    let u = 0
    while(size >= BYTES_PER_KB && u < UNITS.length-1) {
        size /= BYTES_PER_KB
        ++u
    }

    return new Intl.NumberFormat([], {
        style: 'unit',
        unit: UNITS[u],
        unitDisplay: 'short',
        maximumFractionDigits: 1,
    }).format(size)
}

将[]替换为像fr这样的语言代码,以强制进行默认以外的本地化。

console.log(humanFileSize(0))
console.log(humanFileSize(9))
console.log(humanFileSize(99))
console.log(humanFileSize(999))
console.log(humanFileSize(1000))
console.log(humanFileSize(1001))
console.log(humanFileSize(1023))
console.log(humanFileSize(1024))
console.log(humanFileSize(1025))
console.log(humanFileSize(100_000))
console.log(humanFileSize(1_000_000))
console.log(humanFileSize(1_000_000_000))
console.log(humanFileSize(1_000_000_000_000))
console.log(humanFileSize(1_000_000_000_000_000))
console.log(humanFileSize(1_000_000_000_000_000_000))
// fr
0 o
9 o
99 o
999 o
1 ko
1 ko
1 ko
1 ko
1 ko
100 ko
1 Mo
1 Go
1 To
1 Po
1 000 Po

// en-US
0 byte
9 byte
99 byte
999 byte
1 kB
1 kB
1 kB
1 kB
1 kB
100 kB
1 MB
1 GB
1 TB
1 PB
1,000 PB

你可以得到国际。NumberFormat为您自动进行单位转换。如。

const sizeFormatter = new Intl.NumberFormat([], { style: 'unit', unit: 'byte', notation: "compact", unitDisplay: "narrow", }) console.log(sizeFormatter.format(0)) console.log(sizeFormatter.format(1)) console.log(sizeFormatter.format(999)) console.log(sizeFormatter.format(1000)) console.log(sizeFormatter.format(1023)) console.log(sizeFormatter.format(1024)) console.log(sizeFormatter.format(1024**2)) console.log(sizeFormatter.format(1024**3)) console.log(sizeFormatter.format(1024**4)) console.log(sizeFormatter.format(1024**5)) console.log(sizeFormatter.format(1024**6))

...但是单位有点奇怪。例如1024**4是1.1BB,我猜是“十亿字节”;我不认为有人会用它,即使它在技术上是正确的。

一个简单而简短的“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));