From ee1bc18e04f02349f71a40015d281d1caeed40fc Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Sun, 10 Apr 2022 04:02:29 +0200 Subject: [PATCH] filesize in humanreadable format (#12012) --- .../FileSizeFormatUtil.java | 81 +++++++++++++++++++ .../FileSizeFormatUtilUnitTest.java | 40 +++++++++ 2 files changed, 121 insertions(+) create mode 100644 java-numbers-4/src/main/java/com/baeldung/humanreadablebytes/FileSizeFormatUtil.java create mode 100644 java-numbers-4/src/test/java/com/baeldung/humanreadablebytes/FileSizeFormatUtilUnitTest.java diff --git a/java-numbers-4/src/main/java/com/baeldung/humanreadablebytes/FileSizeFormatUtil.java b/java-numbers-4/src/main/java/com/baeldung/humanreadablebytes/FileSizeFormatUtil.java new file mode 100644 index 0000000000..941aa105aa --- /dev/null +++ b/java-numbers-4/src/main/java/com/baeldung/humanreadablebytes/FileSizeFormatUtil.java @@ -0,0 +1,81 @@ +package com.baeldung.humanreadablebytes; + +import java.text.DecimalFormat; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class FileSizeFormatUtil { + private static final long BYTE = 1L; + private static final long KB = BYTE << 10; + private static final long MB = KB << 10; + private static final long GB = MB << 10; + private static final long TB = GB << 10; + private static final long PB = TB << 10; + private static final long EB = PB << 10; + private static final DecimalFormat DEC_FORMAT = new DecimalFormat("#.##"); + + public static String toHumanReadable(long size) { + if (size < 0) + throw new IllegalArgumentException("Invalid file size: " + size); + if (size >= EB) return formatSize(size, EB, "EB"); + if (size >= PB) return formatSize(size, PB, "PB"); + if (size >= TB) return formatSize(size, TB, "TB"); + if (size >= GB) return formatSize(size, GB, "GB"); + if (size >= MB) return formatSize(size, MB, "MB"); + if (size >= KB) return formatSize(size, KB, "KB"); + return formatSize(size, BYTE, "Bytes"); + } + + private static String formatSize(long size, long divider, String unitName) { + return DEC_FORMAT.format((double) size / divider) + " " + unitName; + } + + public static String toHumanReadableWithEnum(long size) { + final List units = SizeUnit.unitsInDescending(); + if (size < 0) + throw new IllegalArgumentException("Invalid file size: " + size); + String result = null; + for (SizeUnit unit : units) { + if (size >= unit.getUnitBase()) { + result = formatSize(size, unit.getUnitBase(), unit.name()); + break; + } + } + return result == null ? formatSize(size, SizeUnit.Bytes.getUnitBase(), SizeUnit.Bytes.name()) : result; + } + + public static String toHumanReadableByNumOfLeadingZeros(long size) { + if (size < 0) + throw new IllegalArgumentException("Invalid file size: " + size); + if (size < 1024) return size + " Bytes"; + int unitIdx = (63 - Long.numberOfLeadingZeros(size)) / 10; + return formatSize(size, 1L << (unitIdx * 10), " KMGTPE".charAt(unitIdx) + "B"); + } + + enum SizeUnit { + Bytes(1L), + KB(Bytes.unitBase << 10), + MB(KB.unitBase << 10), + GB(MB.unitBase << 10), + TB(GB.unitBase << 10), + PB(TB.unitBase << 10), + EB(PB.unitBase << 10); + + private final Long unitBase; + + public static List unitsInDescending() { + List list = Arrays.asList(values()); + Collections.reverse(list); + return list; + } + + public Long getUnitBase() { + return unitBase; + } + + SizeUnit(long unitBase) { + this.unitBase = unitBase; + } + } +} diff --git a/java-numbers-4/src/test/java/com/baeldung/humanreadablebytes/FileSizeFormatUtilUnitTest.java b/java-numbers-4/src/test/java/com/baeldung/humanreadablebytes/FileSizeFormatUtilUnitTest.java new file mode 100644 index 0000000000..4326e92e2f --- /dev/null +++ b/java-numbers-4/src/test/java/com/baeldung/humanreadablebytes/FileSizeFormatUtilUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.humanreadablebytes; + +import org.apache.commons.io.FileUtils; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +public class FileSizeFormatUtilUnitTest { + private final static Map DATA_MAP = new HashMap() {{ + put(0L, "0 Bytes"); + put(1023L, "1023 Bytes"); + put(1024L, "1 KB"); + put(12_345L, "12.06 KB"); + put(10_123_456L, "9.65 MB"); + put(10_123_456_798L, "9.43 GB"); + put(1_777_777_777_777_777_777L, "1.54 EB"); + }}; + + @Test + public void givenBytes_whenCalltoHumanReadableMethod_thenGetExpectedResults() { + DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadable(in))); + } + + @Test + public void givenBytes_whenCalltoHumanReadableWithEnumMethod_thenGetExpectedResults() { + DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableWithEnum(in))); + } + + @Test + public void givenBytes_whenCalltoHumanReadableByLeadingZeros_thenGetExpectedResults() { + DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableByNumOfLeadingZeros(in))); + } + + @Test + public void givenBytes_whenCalltoHumanReadableByFileUtils_thenOutputExpectedResults() { + DATA_MAP.forEach((in, expected) -> System.out.println(in + " bytes -> " + FileUtils.byteCountToDisplaySize(in))); + } +}