From 662f3c4f3e07183c2b9632b21cc9ceb4eac1bfb8 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Sat, 16 Jul 2022 14:28:46 +0530 Subject: [PATCH] JAVA-13328 Update Convert Byte Size Into a Human-Readable Format in Java --- .../FileSizeFormatUtil.java | 108 ++++++++++++++---- .../FileSizeFormatUtilUnitTest.java | 46 +++++--- 2 files changed, 117 insertions(+), 37 deletions(-) diff --git a/core-java-modules/core-java-numbers-4/src/main/java/com/baeldung/humanreadablebytes/FileSizeFormatUtil.java b/core-java-modules/core-java-numbers-4/src/main/java/com/baeldung/humanreadablebytes/FileSizeFormatUtil.java index 941aa105aa..b4e262c95e 100644 --- a/core-java-modules/core-java-numbers-4/src/main/java/com/baeldung/humanreadablebytes/FileSizeFormatUtil.java +++ b/core-java-modules/core-java-numbers-4/src/main/java/com/baeldung/humanreadablebytes/FileSizeFormatUtil.java @@ -7,15 +7,35 @@ 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 long KiB = BYTE << 10; + private static final long MiB = KiB << 10; + private static final long GiB = MiB << 10; + private static final long TiB = GiB << 10; + private static final long PiB = TiB << 10; + private static final long EiB = PiB << 10; + + private static final long KB = BYTE * 1000; + private static final long MB = KB * 1000; + private static final long GB = MB * 1000; + private static final long TB = GB * 1000; + private static final long PB = TB * 1000; + private static final long EB = PB * 1000; + private static final DecimalFormat DEC_FORMAT = new DecimalFormat("#.##"); - public static String toHumanReadable(long size) { + public static String toHumanReadableBinaryPrefixes(long size) { + if (size < 0) + throw new IllegalArgumentException("Invalid file size: " + size); + if (size >= EiB) return formatSize(size, EiB, "EiB"); + if (size >= PiB) return formatSize(size, PiB, "PiB"); + if (size >= TiB) return formatSize(size, TiB, "TiB"); + if (size >= GiB) return formatSize(size, GiB, "GiB"); + if (size >= MiB) return formatSize(size, MiB, "MiB"); + if (size >= KiB) return formatSize(size, KiB, "KiB"); + return formatSize(size, BYTE, "Bytes"); + } + + public static String toHumanReadableSIPrefixes(long size) { if (size < 0) throw new IllegalArgumentException("Invalid file size: " + size); if (size >= EB) return formatSize(size, EB, "EB"); @@ -26,23 +46,37 @@ public class FileSizeFormatUtil { 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(); + public static String toHumanReadableBinaryPrefixesWithEnum(long size) { + final List units = SizeUnitBinaryPrefixes.unitsInDescending(); if (size < 0) throw new IllegalArgumentException("Invalid file size: " + size); String result = null; - for (SizeUnit unit : units) { + for (SizeUnitBinaryPrefixes 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; + return result == null ? formatSize(size, SizeUnitBinaryPrefixes.Bytes.getUnitBase(), SizeUnitBinaryPrefixes.Bytes.name()) : result; + } + + public static String toHumanReadableSIPrefixesWithEnum(long size) { + final List units = SizeUnitSIPrefixes.unitsInDescending(); + if (size < 0) + throw new IllegalArgumentException("Invalid file size: " + size); + String result = null; + for (SizeUnitSIPrefixes unit : units) { + if (size >= unit.getUnitBase()) { + result = formatSize(size, unit.getUnitBase(), unit.name()); + break; + } + } + return result == null ? formatSize(size, SizeUnitSIPrefixes.Bytes.getUnitBase(), SizeUnitSIPrefixes.Bytes.name()) : result; } public static String toHumanReadableByNumOfLeadingZeros(long size) { @@ -50,22 +84,22 @@ public class FileSizeFormatUtil { 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"); + return formatSize(size, 1L << (unitIdx * 10), " KMGTPE".charAt(unitIdx) + "iB"); } - - enum SizeUnit { + + enum SizeUnitBinaryPrefixes { 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); + KiB(Bytes.unitBase << 10), + MiB(KiB.unitBase << 10), + GiB(MiB.unitBase << 10), + TiB(GiB.unitBase << 10), + PiB(TiB.unitBase << 10), + EiB(PiB.unitBase << 10); private final Long unitBase; - public static List unitsInDescending() { - List list = Arrays.asList(values()); + public static List unitsInDescending() { + List list = Arrays.asList(values()); Collections.reverse(list); return list; } @@ -74,7 +108,33 @@ public class FileSizeFormatUtil { return unitBase; } - SizeUnit(long unitBase) { + SizeUnitBinaryPrefixes(long unitBase) { + this.unitBase = unitBase; + } + } + + enum SizeUnitSIPrefixes { + Bytes(1L), + KB(Bytes.unitBase * 1000), + MB(KB.unitBase * 1000), + GB(MB.unitBase * 1000), + TB(GB.unitBase * 1000), + PB(TB.unitBase * 1000), + EB(PB.unitBase * 1000); + + private final Long unitBase; + + public static List unitsInDescending() { + List list = Arrays.asList(values()); + Collections.reverse(list); + return list; + } + + public Long getUnitBase() { + return unitBase; + } + + SizeUnitSIPrefixes(long unitBase) { this.unitBase = unitBase; } } diff --git a/core-java-modules/core-java-numbers-4/src/test/java/com/baeldung/humanreadablebytes/FileSizeFormatUtilUnitTest.java b/core-java-modules/core-java-numbers-4/src/test/java/com/baeldung/humanreadablebytes/FileSizeFormatUtilUnitTest.java index 4326e92e2f..497fdc5792 100644 --- a/core-java-modules/core-java-numbers-4/src/test/java/com/baeldung/humanreadablebytes/FileSizeFormatUtilUnitTest.java +++ b/core-java-modules/core-java-numbers-4/src/test/java/com/baeldung/humanreadablebytes/FileSizeFormatUtilUnitTest.java @@ -8,33 +8,53 @@ import java.util.HashMap; import java.util.Map; public class FileSizeFormatUtilUnitTest { - private final static Map DATA_MAP = new HashMap() {{ + private final static Map DATA_MAP_BINARY_PREFIXES = 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"); + put(1024L, "1 KiB"); + put(12_345L, "12.06 KiB"); + put(10_123_456L, "9.65 MiB"); + put(10_123_456_798L, "9.43 GiB"); + put(1_777_777_777_777_777_777L, "1.54 EiB"); }}; + private final static Map DATA_MAP_SI_PREFIXES = new HashMap() {{ + put(0L, "0 Bytes"); + put(999L, "999 Bytes"); + put(1000L, "1 KB"); + put(12_345L, "12.35 KB"); + put(10_123_456L, "10.12 MB"); + put(10_123_456_798L, "10.12 GB"); + put(1_777_777_777_777_777_777L, "1.78 EB"); + }}; + @Test - public void givenBytes_whenCalltoHumanReadableMethod_thenGetExpectedResults() { - DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadable(in))); + public void givenBytes_whenCalltoHumanReadableBinaryPrefixesMethod_thenGetExpectedResults() { + DATA_MAP_BINARY_PREFIXES.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableBinaryPrefixes(in))); + } + + @Test + public void givenBytes_whenCalltoHumanReadableSIPrefixesMethod_thenGetExpectedResults() { + DATA_MAP_SI_PREFIXES.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableSIPrefixes(in))); } @Test - public void givenBytes_whenCalltoHumanReadableWithEnumMethod_thenGetExpectedResults() { - DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableWithEnum(in))); + public void givenBytes_whenCalltoHumanReadableBinaryPrefixesWithEnumMethod_thenGetExpectedResults() { + DATA_MAP_BINARY_PREFIXES.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableBinaryPrefixesWithEnum(in))); } + @Test + public void givenBytes_whenCalltoHumanReadableSIPrefixesWithEnumMethod_thenGetExpectedResults() { + DATA_MAP_SI_PREFIXES.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableSIPrefixesWithEnum(in))); + } + @Test public void givenBytes_whenCalltoHumanReadableByLeadingZeros_thenGetExpectedResults() { - DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableByNumOfLeadingZeros(in))); + DATA_MAP_BINARY_PREFIXES.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))); + DATA_MAP_BINARY_PREFIXES.forEach((in, expected) -> System.out.println(in + " bytes -> " + FileUtils.byteCountToDisplaySize(in))); } }