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

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


当前回答

这取决于你是想使用二进制还是十进制约定。

例如,RAM总是用二进制来度量,因此将1551859712表示为~1.4GiB是正确的。

另一方面,硬盘制造商喜欢使用十进制,所以他们称它为~1.6GB。

只是让人迷惑的是,软盘混合使用了这两种系统——它们的1MB实际上是1024000字节。

其他回答

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

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

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

到2020年,你可以使用文件大小的npm包,它支持IEC(功率1024,默认),SI(功率1000)和JEDEC(替代SI单位符号)格式。

npm install file-size

import filesize from "filesize";

// outputs: 186.46 MB
filesize(186457865).human('si');

// outputs: 177.82 MiB
filesize(186457865).human();

https://www.npmjs.com/package/file-size

解决方案作为ReactJS组件

Bytes = React.createClass({
    formatBytes() {
        var i = Math.floor(Math.log(this.props.bytes) / Math.log(1024));
        return !this.props.bytes && '0 Bytes' || (this.props.bytes / Math.pow(1024, i)).toFixed(2) + " " + ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'][i]
    },
    render () {
        return (
            <span>{ this.formatBytes() }</span>
        );
    }
});

更新 对于那些使用es6的人来说,这里是同一个组件的无状态版本

const sufixes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const getBytes = (bytes) => {
  const i = Math.floor(Math.log(bytes) / Math.log(1024));
  return !bytes && '0 Bytes' || (bytes / Math.pow(1024, i)).toFixed(2) + " " + sufixes[i];
};

const Bytes = ({ bytes }) => (<span>{ getBytes(bytes) }</span>);

Bytes.propTypes = {
  bytes: React.PropTypes.number,
};

这取决于你是想使用二进制还是十进制约定。

例如,RAM总是用二进制来度量,因此将1551859712表示为~1.4GiB是正确的。

另一方面,硬盘制造商喜欢使用十进制,所以他们称它为~1.6GB。

只是让人迷惑的是,软盘混合使用了这两种系统——它们的1MB实际上是1024000字节。

我的回答可能晚了,但我想它会帮助到某人。

度量前缀:

/**
 * Format file size in metric prefix
 * @param fileSize
 * @returns {string}
 */
const formatFileSizeMetric = (fileSize) => {
  let size = Math.abs(fileSize);

  if (Number.isNaN(size)) {
    return 'Invalid file size';
  }

  if (size === 0) {
    return '0 bytes';
  }

  const units = ['bytes', 'kB', 'MB', 'GB', 'TB'];
  let quotient = Math.floor(Math.log10(size) / 3);
  quotient = quotient < units.length ? quotient : units.length - 1;
  size /= (1000 ** quotient);

  return `${+size.toFixed(2)} ${units[quotient]}`;
};

二进制前缀:

/**
 * Format file size in binary prefix
 * @param fileSize
 * @returns {string}
 */
const formatFileSizeBinary = (fileSize) => {
  let size = Math.abs(fileSize);

  if (Number.isNaN(size)) {
    return 'Invalid file size';
  }

  if (size === 0) {
    return '0 bytes';
  }

  const units = ['bytes', 'kiB', 'MiB', 'GiB', 'TiB'];
  let quotient = Math.floor(Math.log2(size) / 10);
  quotient = quotient < units.length ? quotient : units.length - 1;
  size /= (1024 ** quotient);

  return `${+size.toFixed(2)} ${units[quotient]}`;
};

例子:

// Metrics prefix
formatFileSizeMetric(0)      // 0 bytes
formatFileSizeMetric(-1)     // 1 bytes
formatFileSizeMetric(100)    // 100 bytes
formatFileSizeMetric(1000)   // 1 kB
formatFileSizeMetric(10**5)  // 10 kB
formatFileSizeMetric(10**6)  // 1 MB
formatFileSizeMetric(10**9)  // 1GB
formatFileSizeMetric(10**12) // 1 TB
formatFileSizeMetric(10**15) // 1000 TB

// Binary prefix
formatFileSizeBinary(0)     // 0 bytes
formatFileSizeBinary(-1)    // 1 bytes
formatFileSizeBinary(1024)  // 1 kiB
formatFileSizeBinary(2048)  // 2 kiB
formatFileSizeBinary(2**20) // 1 MiB
formatFileSizeBinary(2**30) // 1 GiB
formatFileSizeBinary(2**40) // 1 TiB
formatFileSizeBinary(2**50) // 1024 TiB