views:

129

answers:

1

I need to display a file size as String using sensible units.

e.g.

1L ==> "1 B";
1024L ==> "1 KB";
2537253L ==> "2.3 MB"

etc.

I found this previous answer, which I didn't find satisfatory

I have come up with my own solution which has similar shortcomings:

private static final long K = 1024;
private static final long M = K * K;
private static final long G = M * K;
private static final long T = G * K;

public static String convertToStringRepresentation(final long value){
    final long[] dividers = new long[] { T, G, M, K, 1 };
    final String[] units = new String[] { "TB", "GB", "MB", "KB", "B" };
    if(value < 1)
        throw new IllegalArgumentException("Invalid file size: " + value);
    String result = null;
    for(int i = 0; i < dividers.length; i++){
        final long divider = dividers[i];
        if(value >= divider){
            result = format(value, divider, units[i]);
            break;
        }
    }
    return result;
}

private static String format(final long value,
    final long divider,
    final String unit){
    final double result =
        divider > 1 ? (double) value / (double) divider : (double) value;
    return String.format("%.1f %s", Double.valueOf(result), unit);
}

The main problem is my limited knowledge of Decimalformat and / or String.format. I would like 1024L, 1025L etc to map to 1 KB rather than 1.0 KB.

So, two possibilities:

  1. I would prefer a good out-of-the-box solution in a public library like apache commons or google guava.
  2. If there isn't, can someone show me how to get rid of the '.0' part (without resorting to string replacement and regex, I can do that myself)
+3  A: 

You'll probably have more luck with java.text.DecimalFormat. This code should probably do it (just winging it though...)

new DecimalFormat("#,##0.#").format(value) + " " + unit

Robert Watkins
perfect, thanks!
seanizer