Java 将文件大小格式化为 MB、GB 等

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3263892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 19:07:59  来源:igfitidea点击:

Format file size as MB, GB etc

javastringformatnumbers

提问by Sean Patrick Floyd

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 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 KBrather than 1.0 KB.

主要问题是我对 Decimalformat 和/或 String.format 的了解有限。我希望 1024L、1025L 等映射到1 KB而不是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)
  1. 我更喜欢公共图书馆(如 apache commons 或 google guava)中的良好开箱即用解决方案。
  2. 如果没有,有人可以告诉我如何摆脱 '.0' 部分(不诉诸字符串替换和正则表达式,我可以自己做)

采纳答案by Mr Ed

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!

这将工作到 1000 TB ......而且程序很短!

回答by Robert Watkins

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

你可能会有更多的运气java.text.DecimalFormat。这段代码应该可以做到(尽管只是翼翼......)

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

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

回答by R Jobs

Surprisingly for me but loop based algorithm is about 10% faster.

令我惊讶的是,基于循环的算法快了大约 10%。

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));
}