diff --git a/CHANGELOG.md b/CHANGELOG.md index c5b72a602..61e0d2f20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,11 @@ ------------------------------------------------------------------------------------------------------------- -## 5.3.10 (2020-07-14) +## 5.3.10 (2020-07-16) ### 新特性 * 【db 】 增加DbUtil.setReturnGeneratedKeyGlobal(issue#I1NM0K@Gitee) +* 【core 】 增加DataSize和DataSizeUtil(issue#967@Github) ### Bug修复 * 【core 】 修复ZipUtil中finish位于循环内的问题(issue#961@Github) diff --git a/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java index 79a5313b0..310c74ef6 100644 --- a/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/io/FileUtil.java @@ -9,6 +9,7 @@ import cn.hutool.core.io.file.FileWriter; import cn.hutool.core.io.file.LineSeparator; import cn.hutool.core.io.file.Tailer; import cn.hutool.core.io.resource.ResourceUtil; +import cn.hutool.core.io.unit.DataSizeUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.CharUtil; @@ -50,7 +51,6 @@ import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; -import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -3361,14 +3361,10 @@ public class FileUtil { * * @param size Long类型大小 * @return 大小 + * @see DataSizeUtil#format(long) */ public static String readableFileSize(long size) { - if (size <= 0) { - return "0"; - } - final String[] units = new String[]{"B", "kB", "MB", "GB", "TB", "EB"}; - int digitGroups = (int) (Math.log10(size) / Math.log10(1024)); - return new DecimalFormat("#,##0.##").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups]; + return DataSizeUtil.format(size); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/io/unit/DataSize.java b/hutool-core/src/main/java/cn/hutool/core/io/unit/DataSize.java new file mode 100644 index 000000000..da01c45a2 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/io/unit/DataSize.java @@ -0,0 +1,277 @@ +package cn.hutool.core.io.unit; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 数据大小,可以将类似于'12MB'表示转换为bytes长度的数字 + *
+ * 此类来自于:Spring-framework + * + *
+ *
Term | Data Size | Size in Bytes |
---|---|---|
byte | 1B | 1 |
kilobyte | 1KB | 1,024 |
megabyte | 1MB | 1,048,576 |
gigabyte | 1GB | 1,073,741,824 |
terabyte | 1TB | 1,099,511,627,776 |
+ * 例如: + *
+ * "12KB" -- parses as "12 kilobytes" + * "5MB" -- parses as "5 megabytes" + * "20" -- parses as "20 bytes" + *+ * + * @param text the text to parse + * @return the parsed {@link DataSize} + * @see #parse(CharSequence, DataUnit) + */ + public static DataSize parse(CharSequence text) { + return parse(text, null); + } + + /** + * Obtain a {@link DataSize} from a text string such as {@code 12MB} using + * the specified default {@link DataUnit} if no unit is specified. + *
+ * The string starts with a number followed optionally by a unit matching one of the + * supported {@linkplain DataUnit suffixes}. + *
+ * Examples: + *
+ * "12KB" -- parses as "12 kilobytes" + * "5MB" -- parses as "5 megabytes" + * "20" -- parses as "20 kilobytes" (where the {@code defaultUnit} is {@link DataUnit#KILOBYTES}) + *+ * + * @param text the text to parse + * @return the parsed {@link DataSize} + */ + public static DataSize parse(CharSequence text, DataUnit defaultUnit) { + Assert.notNull(text, "Text must not be null"); + try { + Matcher matcher = PATTERN.matcher(text); + Assert.state(matcher.matches(), "Does not match data size pattern"); + DataUnit unit = determineDataUnit(matcher.group(2), defaultUnit); + long amount = Long.parseLong(matcher.group(1)); + return DataSize.of(amount, unit); + } catch (Exception ex) { + throw new IllegalArgumentException("'" + text + "' is not a valid data size", ex); + } + } + + /** + * 决定数据单位,后缀不识别时使用默认单位 + * @param suffix 后缀 + * @param defaultUnit 默认单位 + * @return {@link DataUnit} + */ + private static DataUnit determineDataUnit(String suffix, DataUnit defaultUnit) { + DataUnit defaultUnitToUse = (defaultUnit != null ? defaultUnit : DataUnit.BYTES); + return (StrUtil.isNotEmpty(suffix) ? DataUnit.fromSuffix(suffix) : defaultUnitToUse); + } + + /** + * 是否为负数,不包括0 + * + * @return 负数返回true,否则false + */ + public boolean isNegative() { + return this.bytes < 0; + } + + /** + * 返回bytes大小 + * + * @return bytes大小 + */ + public long toBytes() { + return this.bytes; + } + + /** + * 返回KB大小 + * + * @return KB大小 + */ + public long toKilobytes() { + return this.bytes / BYTES_PER_KB; + } + + /** + * 返回MB大小 + * + * @return MB大小 + */ + public long toMegabytes() { + return this.bytes / BYTES_PER_MB; + } + + /** + * 返回GB大小 + * + * @return GB大小 + * + */ + public long toGigabytes() { + return this.bytes / BYTES_PER_GB; + } + + /** + * 返回TB大小 + * + * @return TB大小 + */ + public long toTerabytes() { + return this.bytes / BYTES_PER_TB; + } + + @Override + public int compareTo(DataSize other) { + return Long.compare(this.bytes, other.bytes); + } + + @Override + public String toString() { + return String.format("%dB", this.bytes); + } + + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other == null || getClass() != other.getClass()) { + return false; + } + DataSize otherSize = (DataSize) other; + return (this.bytes == otherSize.bytes); + } + + @Override + public int hashCode() { + return Long.hashCode(this.bytes); + } + +} diff --git a/hutool-core/src/main/java/cn/hutool/core/io/unit/DataSizeUtil.java b/hutool-core/src/main/java/cn/hutool/core/io/unit/DataSizeUtil.java new file mode 100644 index 000000000..e38e87d42 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/io/unit/DataSizeUtil.java @@ -0,0 +1,38 @@ +package cn.hutool.core.io.unit; + +import java.text.DecimalFormat; + +/** + * 数据大小工具类 + * + * @author looly + * @since 5.3.10 + */ +public class DataSizeUtil { + + /** + * 解析数据大小字符串,转换为bytes大小 + * + * @param text 数据大小字符串,类似于:12KB, 5MB等 + * @return bytes大小 + */ + public long parse(String text) { + return DataSize.parse(text).toBytes(); + } + + /** + * 可读的文件大小
+ * 此类来自于:Spring-framework + * + *
+ *
名称 | 数据大小 | Power of 2 | bytes表示 |
---|---|---|---|
{@link #BYTES} | 1B | 2^0 | 1 |
{@link #KILOBYTES} | 1KB | 2^10 | 1,024 |
{@link #MEGABYTES} | 1MB | 2^20 | 1,048,576 |
{@link #GIGABYTES} | 1GB | 2^30 | 1,073,741,824 |
{@link #TERABYTES} | 1TB | 2^40 | 1,099,511,627,776 |