How to Convert Byte Size into a Human-Readable Format in Java

How can I convert byte size into a human-readable format in Java?

Fun fact: The original snippet posted here was the most copied Java snippet of all time on Stack Overflow, and it was flawed. It was fixed, but it got messy.

Full story in this article: The most copied Stack Overflow snippet of all time is flawed!

Source: Formatting byte size to human readable format | Programming.Guide

SI (1 k = 1,000)

public static String humanReadableByteCountSI(long bytes) {
if (-1000 < bytes && bytes < 1000) {
return bytes + " B";
}
CharacterIterator ci = new StringCharacterIterator("kMGTPE");
while (bytes <= -999_950 || bytes >= 999_950) {
bytes /= 1000;
ci.next();
}
return String.format("%.1f %cB", bytes / 1000.0, ci.current());
}

Binary (1 Ki = 1,024)

public static String humanReadableByteCountBin(long bytes) {
long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
if (absB < 1024) {
return bytes + " B";
}
long value = absB;
CharacterIterator ci = new StringCharacterIterator("KMGTPE");
for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
value >>= 10;
ci.next();
}
value *= Long.signum(bytes);
return String.format("%.1f %ciB", value / 1024.0, ci.current());
}

Example output:

                             SI     BINARY

0: 0 B 0 B
27: 27 B 27 B
999: 999 B 999 B
1000: 1.0 kB 1000 B
1023: 1.0 kB 1023 B
1024: 1.0 kB 1.0 KiB
1728: 1.7 kB 1.7 KiB
110592: 110.6 kB 108.0 KiB
7077888: 7.1 MB 6.8 MiB
452984832: 453.0 MB 432.0 MiB
28991029248: 29.0 GB 27.0 GiB
1855425871872: 1.9 TB 1.7 TiB
9223372036854775807: 9.2 EB 8.0 EiB (Long.MAX_VALUE)

convert byte size into human readable format in Java?

You're dividing by bits but your input is already in bytes, not bits. So except for the < KB calculation you're ending up with results that are all 1/8th of the expected size calculations.

Give the following code a whirl (print statements added just to sanity check the divisors):

        double KiB = Math.pow(2, 10);
double MiB = Math.pow(2, 20);
double GiB = Math.pow(2, 30);
double TiB = Math.pow(2, 40);
double Pib = Math.pow(2, 50);

NumberFormat df = DecimalFormat.getInstance();
System.out.println("KiB: " + df.format(KiB));
System.out.println("MiB: " + df.format(MiB));
System.out.println("GiB: " + df.format(GiB));
System.out.println("TiB: " + df.format(TiB));
System.out.println("Pib: " + df.format(Pib));

if (size < KiB) {
return size + " byte";

} else if (size < MiB) {
double result = size / KiB;
return floatForm(result) + " KiB";

/* remaining code is identical to yours */

How to convert byte size into human readable format in Kotlin?

There's a more concise solution:

fun bytesToHumanReadableSize(bytes: Double) = when {
bytes >= 1 shl 30 -> "%.1f GB".format(bytes / (1 shl 30))
bytes >= 1 shl 20 -> "%.1f MB".format(bytes / (1 shl 20))
bytes >= 1 shl 10 -> "%.0f kB".format(bytes / (1 shl 10))
else -> "$bytes bytes"
}

How to convert byte array into Human readable format?

byte[] byteArray = new byte[] {87, 79, 87, 46, 46, 46};

String value = new String(byteArray);

How can I convert file size human-readable format into byte size in Java?

You can use an enum like this

public static void main(String[] args) {

System.out.println(10 * UNIT.calculateBytes("MB"));
}

enum UNIT {
B(1000), KB(1000), MB(1000), GB(1000), TB(1000);

private int timesThanPreviousUnit;

UNIT(int timesThanPreviousUnit) {
this.timesThanPreviousUnit = timesThanPreviousUnit;
}

public static long calculateBytes(String symbol) {
long inBytes = 1;
UNIT inputUnit = UNIT.valueOf(symbol);
UNIT[] UNITList = UNIT.values();

for (UNIT unit : UNITList) {
if (inputUnit.equals(unit)) {
return inBytes;
}
inBytes *= unit.timesThanPreviousUnit;
}
return inBytes;
}
}

Framework to convert bytes into readable values

You may want to check out Apache Commons FileUtils.byteCountToDisplaySize(long). It handles all possible (non-negative) values of a long.

Usage:

import org.apache.commons.io.FileUtils;

long fileSizeBytes = ...;
FileUtils.byteCountToDisplaySize(fileSizeBytes);

Java - Convert Human Readable Size to Bytes

I've never heard about such well-known library, which implements such text-parsing utility methods. But your solution seems to be near from correct implementation.

The only two things, which I'd like to correct in your code are:

  1. define method Number parse(String arg0) as static due to it utility nature

  2. define factors for each type of size definition as final static fields.

I.e. it will be like this one:

private final static long KB_FACTOR = 1024;
private final static long MB_FACTOR = 1024 * KB_FACTOR;
private final static long GB_FACTOR = 1024 * MB_FACTOR;

public static double parse(String arg0) {
int spaceNdx = arg0.indexOf(" ");
double ret = Double.parseDouble(arg0.substring(0, spaceNdx));
switch (arg0.substring(spaceNdx + 1)) {
case "GB":
return ret * GB_FACTOR;
case "MB":
return ret * MB_FACTOR;
case "KB":
return ret * KB_FACTOR;
}
return -1;
}

Format file size as MB, GB, etc

public static String readableFileSize(long size) {
if(size <= 0) return "0";
final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" };
int digitGroups = (int) (Math.log10(size)/Math.log10(1024));
return new DecimalFormat("#,##0.#").format(size/Math.pow(1024, digitGroups)) + " " + units[digitGroups];
}

This will work up to 1000 TB.... and the program is short!

Bytes in human-readable format with idiomatic Scala

My version:

/**
* Converts a number of bytes into a human-readable string
* such as `2.2 MB` or `8.0 EiB`.
*
* @param bytes the number of bytes we want to convert
* @param si if true, we use base 10 SI units where 1000 bytes are 1 kB.
* If false, we use base 2 IEC units where 1024 bytes are 1 KiB.
* @return the bytes as a human-readable string
*/
def humanReadableSize(bytes: Long, si: Boolean): String = {

// See https://en.wikipedia.org/wiki/Byte
val (baseValue, unitStrings) =
if (si)
(1000, Vector("B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"))
else
(1024, Vector("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"))

def getExponent(curBytes: Long, baseValue: Int, curExponent: Int = 0): Int =
if (curBytes < baseValue) curExponent
else {
val newExponent = 1 + curExponent
getExponent(curBytes / (baseValue * newExponent), baseValue, newExponent)
}

val exponent = getExponent(bytes, baseValue)
val divisor = Math.pow(baseValue, exponent)
val unitString = unitStrings(exponent)

// Divide the bytes and show one digit after the decimal point
f"${bytes / divisor}%.1f $unitString"
}

Usage examples:

// Result: 1.0 kB
humanReadableSize(1000, si = true)

// Result: 1000.0 B
humanReadableSize(1000, si = false)

// Result: 10.0 kB
humanReadableSize(10000, si = true)

// Result: 9.8 KiB
humanReadableSize(10000, si = false)

// Result: 49.1 GB
humanReadableSize(49134421234L, si = true)

// Result: 45.8 GiB
humanReadableSize(49134421234L, si = false)


Related Topics



Leave a reply



Submit