Format file size as MB, GB, etc [duplicate]
I need to display a file size as a string using sensible units.
For example,
1L ==> "1 B";
1024L ==> "1 KB";
2537253L ==> "2.3 MB"
etc.
I found this previous answer, which I didn't find satisfactory.
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:
- I would prefer a good out-of-the-box solution in a public library like Apache Commons or Google Guava.
- If there isn't, how can I get rid of the '.0' part (without resorting to string replacement and regex, I can do that myself)?
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!
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
It is surprising for me, but a loop-based algorithm is about 10% faster.
public static String toNumInUnits(long bytes) {
int u = 0;
for ( ; bytes > 1024*1024; bytes >>= 10) {
u++;
}
if (bytes > 1024)
u++;
return String.format("%.1f %cB", bytes/1024f, " kMGTPE".charAt(u));
}
加载中,请稍侯......
精彩评论