add IOSize.parse

This commit is contained in:
Timi
2026-01-05 15:03:44 +08:00
parent 5240b57c47
commit 31879a511d

View File

@ -77,4 +77,96 @@ export default class IOSize {
}
return "0 B";
}
/**
* 将格式化的储存量字符串解析为字节量
* <p>支持格式10GB, 10 GB, 1TB, 1.24 KB 等(单位不区分大小写)</p>
* <pre>
* // 返回 102400
* IOSize.parse("100 KB");
* // 返回 1073741824
* IOSize.parse("1GB");
* </pre>
*
* @param sizeStr 格式化后的储存量字符串
* @return 字节量
* @throws Error 格式无效
*/
public static parse(sizeStr: string): number {
if (!sizeStr || sizeStr.trim() === "") {
throw new Error("not found sizeStr");
}
// 正则匹配:可选符号 + 数字(含小数点)+ 可选空格 + 单位
const pattern = /([-+]?\d+(?:\.\d+)?)\s*([a-zA-Z]+)/;
const matcher = pattern.exec(sizeStr.trim());
if (matcher) {
let value: number;
try {
value = parseFloat(matcher[1]);
} catch (e) {
throw new Error("invalid number format: " + matcher[1]);
}
if (value < 0) {
throw new Error("size cannot be negative: " + value);
}
const unitStr = matcher[2].toUpperCase();
let unit: Unit;
// 先尝试精确匹配枚举
if (Object.values(Unit).includes(unitStr as Unit)) {
unit = unitStr as Unit;
} else {
// 处理单字母单位缩写K/M/G/T/P/E
switch (unitStr.charAt(0)) {
case "K":
unit = Unit.KB;
break;
case "M":
unit = Unit.MB;
break;
case "G":
unit = Unit.GB;
break;
case "T":
unit = Unit.TB;
break;
case "P":
unit = Unit.PB;
break;
case "E":
unit = Unit.EB;
break;
case "B":
unit = Unit.B;
break;
default:
throw new Error("Unknown unit: " + unitStr);
}
}
return IOSize.toBytes(value, unit);
}
// 尝试解析纯数字(无单位,默认字节)
try {
const bytes = parseInt(sizeStr.trim());
if (bytes < 0) {
throw new Error("size cannot be negative: " + bytes);
}
return bytes;
} catch (e) {
throw new Error("invalid size format: " + sizeStr);
}
}
/**
* 转换值到字节量
*
* @param value 值
* @param unit 单位
* @return 字节量
*/
private static toBytes(value: number, unit: Unit): number {
const units = Object.values(Unit);
const ordinal = units.indexOf(unit);
return Math.round(value * Math.pow(1024, ordinal));
}
}