Search code examples
javaformattingnumber-formatting

convert byte size into human readable format in Java?


Am trying to Create a static method String formatSize(long sizeInBytes) This method needs to return the most appropriate representation for the provided file size (in bytes) to a human-readable format with at least 2 decimal places (except for bytes).

here is my code

public class HexEditor {

    public static void main(String[] args) {
        System.out.println(formatSize(2147483647));
        System.out.println(formatSize(123));
        System.out.println(formatSize(83647));
        System.out.println(formatSize(9585631));
        System.out.println(formatSize(188900977659375L));
    }
    public static String floatForm (double d){
       return new DecimalFormat("#.##").format(d);
    }

    public static String formatSize(long size) {


        double B = 1 * 8;
        double kibit = 1024;
        double KiB = B * kibit;
        double MiB = KiB * kibit;
        double GiB = MiB * kibit;
        double TiB = GiB * kibit;
        double Pib = TiB * kibit;

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

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

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

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

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

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

        return "";
    }

}

these are my inputs and expect outputs

Input Output

2147483647          2.00 GiB
123                 123 bytes
83647               81.69 KiB
9585631             9.14 MiB
188900977659375     171.80 TiB

but when my code runs it gives different outputs

    256 MiB
    123 byte
    10.21 KiB
    1.14 MiB
    21.48 TiB

Am I getting wrong? or something


Solution

  • 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 */