我得到这段代码通过PHP隐蔽大小字节。
现在我想使用JavaScript将这些大小转换为人类可读的大小。我尝试将这段代码转换为JavaScript,看起来像这样:
function formatSizeUnits(bytes){
if (bytes >= 1073741824) { bytes = (bytes / 1073741824).toFixed(2) + " GB"; }
else if (bytes >= 1048576) { bytes = (bytes / 1048576).toFixed(2) + " MB"; }
else if (bytes >= 1024) { bytes = (bytes / 1024).toFixed(2) + " KB"; }
else if (bytes > 1) { bytes = bytes + " bytes"; }
else if (bytes == 1) { bytes = bytes + " byte"; }
else { bytes = "0 bytes"; }
return bytes;
}
这是正确的做法吗?有没有更简单的方法?
这是目前排名最高的答案的后续。
边界情况
我发现了一个边缘情况:非常少量的字节!具体来说,当字节数在-1和1之间(独占)时。
例如,考虑0.25字节。在这种情况下,Math.floor(Math.log(0.25) / Math.log(1024))将返回-1。由于-1不是一个有效的索引,formatBytes(0.25)将返回类似“0.25 undefined”的值。
下面是一个使用Wolfram Alpha的边缘情况的示例。
Fix
我通过添加Math来解决这个问题。马克斯(0,…):
数学。max(0, Math.floor(Math.log(bytes) / Math.log(1024))
数学。Max(0,…)确保索引值始终至少为0。
这是一个坚实的有效的方法来转换字节。你唯一需要做的就是安装mathjs库进行精确的计算。复制粘贴即可。
import { multiply, divide, round } from "mathjs";
class Size {
constructor(value, unit) {
this.value = value;
this.unit = unit.toUpperCase();
}
}
async function byteToSize(bytes) {
const B = 1;
const KB = multiply(B, 1024);
const MB = multiply(KB, 1024);
const GB = multiply(MB, 1024);
const TB = multiply(GB, 1024);
const PB = multiply(TB, 1024);
if (bytes <= KB) {
// @returns BYTE
const result = round(divide(bytes, B));
const unit = `B`;
return new Size(result, unit);
}
if (bytes <= MB) {
// @returns KILOBYTE
const result = round(divide(bytes, KB));
const unit = `KB`;
return new Size(result, unit);
}
if (bytes <= GB) {
// @returns MEGABYTE
const result = round(divide(bytes, MB));
const unit = `MB`;
return new Size(result, unit);
}
if (bytes <= TB) {
// @returns GIGABYTE
const result = round(divide(bytes, GB));
const unit = `GB`;
return new Size(result, unit);
}
if (bytes <= PB) {
// @returns TERABYTE
const result = divide(bytes, TB).toFixed(2);
const unit = `TB`;
return new Size(result, unit);
}
if (bytes >= PB) {
// @returns PETABYTE
const result = divide(bytes, PB).toFixed(2);
const unit = `PB`;
return new Size(result, unit);
}
}
更灵活和考虑最大pow尺寸列表
(升级后的l2aelba答案)
function formatBytes(bytes, decimals = 2, isBinary = false) {
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; // or ['B', 'KB', 'MB', 'GB', 'TB']
if (!+bytes) {
return `0 ${sizes[0]}`;
}
const inByte = isBinary ? 1024 : 1000;
const dm = decimals < 0 ? 0 : decimals;
const pow = Math.floor(Math.log(bytes) / Math.log(inByte));
const maxPow = Math.min(pow, sizes.length - 1);
return `${parseFloat((bytes / Math.pow(inByte, maxPow)).toFixed(dm))} ${
sizes[maxPow]
}`;
}
我最初在一个文件上传项目中使用@ al冰岛jm的答案,但最近遇到了一个问题,一个文件是0.98kb,但读取为1.02mb。下面是我现在使用的更新代码。
function formatBytes(bytes){
var kb = 1024;
var ndx = Math.floor( Math.log(bytes) / Math.log(kb) );
var fileSizeTypes = ["bytes", "kb", "mb", "gb", "tb", "pb", "eb", "zb", "yb"];
return {
size: +(bytes / kb / kb).toFixed(2),
type: fileSizeTypes[ndx]
};
}
在像这样添加文件之后,上面的函数将被调用
// In this case `file.size` equals `26060275`
formatBytes(file.size);
// returns `{ size: 24.85, type: "mb" }`
当然,Windows读取的文件为24.8mb,但我对额外的精度很满意。
只是稍微修改了@zayarTun答案的代码,以包括一个额外的参数,表示结果中的小数数(如果小数为零,则不需要显示像15.00 KB这样的结果,而是15 KB就足够了,这就是为什么我在parseFloat()中包装结果值)
bytesForHuman(bytes, decimals = 2) {
let units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
let i = 0
for (i; bytes > 1024; i++) {
bytes /= 1024;
}
return parseFloat(bytes.toFixed(decimals)) + ' ' + units[i]
}