package com.imyeyu.io; import com.imyeyu.java.TimiJava; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 字节大小工具 * * @author 夜雨 * @version 2023-06-01 16:41 */ public class IOSize { /** * 储存单位 * * @author 夜雨 * @version 2022-04-08 14:37 */ public enum Unit { /** B */ B, /** KB */ KB, /** MB */ MB, /** GB */ GB, /** TB */ TB, /** PB */ PB, /** EB */ EB; /** * 转换字节量 * * @param value 值 * @return 该单位值字节量 */ public long toBytes(double value) { return (long) (value * Math.pow(1024, ordinal())); } } /** 1 字节 */ public static long BYTE = 1; /** 1 KB */ public static long KB = BYTE << 10; /** 1 MB */ public static long MB = KB << 10; /** 1 GB */ public static long GB = MB << 10; /** 1 TB */ public static long TB = GB << 10; /** 1 PB */ public static long PB = TB << 10; /** 1 EB */ public static long EB = PB << 10; /** *

格式化一个储存容量,保留两位小数 *

	 *     // 返回 100.01 KB
	 *     Tools.byteFormat(102411, 2);
	 * 
* * @param size 字节大小 * @return 格式化结果 */ public static String format(double size) { return format(size, 2, null); } /** *

格式化一个储存容量 *

	 *     // 返回 100.01 KB
	 *     Tools.byteFormat(102411, 2);
	 * 
* * @param size 字节大小 * @param stopUnit 最高等级,格式化到某单位后不再升级,最低 {@link Unit#B},最高 {@link Unit#EB} * @return 格式化结果 */ public static String format(double size, Unit stopUnit) { return format(size, 2, stopUnit); } /** *

格式化一个储存容量 *

	 *     // 返回 100.01 KB
	 *     Tools.byteFormat(102411, 2);
	 * 
* * @param size 字节大小 * @param decimal 保留小数 * @param stopUnit 最高等级,格式化到某单位后不再升级,最低 {@link Unit#B},最高 {@link Unit#EB} * @return 格式化结果 */ public static String format(double size, int decimal, Unit stopUnit) { final Unit[] unit = Unit.values(); if (0 < size) { for (int i = 0; i < unit.length; i++, size /= 1024d) { if (size <= 1000 || i == unit.length - 1 || unit[i] == stopUnit) { if (i == 0) { // 最小单位不需要小数 return (int) size + " B"; } else { String format = "%." + decimal + "f " + unit[i]; return String.format(format, size); } } } } return "0 B"; } /** *

格式化一个储存容量,不带单位 *

	 *     // 返回 100.01
	 *     Tools.byteFormat(102411, 2);
	 * 
* * @param size 字节大小 * @param decimal 保留小数 * @param stopUnit 最高等级,格式化到某单位后不再升级,最低 {@link Unit#B},最高 {@link Unit#TB} * @return 格式化结果(不带单位) */ public static String formatWithoutUnit(double size, int decimal, Unit stopUnit) { final Unit[] unit = Unit.values(); if (0 < size) { for (int i = 0; i < unit.length; i++, size /= 1024d) { if (size <= 1000 || i == unit.length - 1 || unit[i] == stopUnit) { if (i == 0) { return String.valueOf((int) size); } else { String format = "%." + decimal + "f"; return String.format(format, size); } } } } return "0"; } /** * 将格式化的储存量字符串解析为字节量 *

支持格式:10GB, 10 GB, 1TB, 1.24 KB 等(单位不区分大小写)

*
	 *     // 返回 102400
	 *     IOSize.parse("100 KB");
	 *     // 返回 1073741824
	 *     IOSize.parse("1GB");
	 * 
* * @param sizeStr 格式化后的储存量字符串 * @return 字节量 * @throws IllegalArgumentException 格式无效 */ public static long parse(String sizeStr) { if (TimiJava.isEmpty(sizeStr)) { throw new IllegalArgumentException("not found sizeStr"); } // 正则匹配:可选符号 + 数字(含小数点)+ 可选空格 + 单位 Pattern pattern = Pattern.compile("([-+]?\\d+(?:\\.\\d+)?)\\s*([a-zA-Z]+)"); Matcher matcher = pattern.matcher(sizeStr.trim()); if (matcher.find()) { double value; try { value = Double.parseDouble(matcher.group(1)); } catch (NumberFormatException e) { throw new IllegalArgumentException("invalid number format: " + matcher.group(1), e); } if (value < 0) { throw new IllegalArgumentException("size cannot be negative: " + value); } String unitStr = matcher.group(2).toUpperCase(); Unit unit; try { unit = Unit.valueOf(unitStr); } catch (IllegalArgumentException e) { // 处理单字母单位缩写(K/M/G/T/P/E) unit = switch (unitStr.charAt(0)) { case 'K' -> Unit.KB; case 'M' -> Unit.MB; case 'G' -> Unit.GB; case 'T' -> Unit.TB; case 'P' -> Unit.PB; case 'E' -> Unit.EB; case 'B' -> Unit.B; default -> throw new IllegalArgumentException("Unknown unit: " + unitStr); }; } return unit.toBytes(value); } // 尝试解析纯数字(无单位,默认字节) try { long bytes = Long.parseLong(sizeStr.trim()); if (bytes < 0) { throw new IllegalArgumentException("size cannot be negative: " + bytes); } return bytes; } catch (NumberFormatException e) { throw new IllegalArgumentException("invalid size format: " + sizeStr, e); } } }