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 |