如何在Java中将字节大小转换为人类可读的格式?


556

如何在Java中将字节大小转换为人类可读的格式?例如1024应该变成“ 1 Kb”,而1024 * 1024应该变成“ 1 Mb”。

我有点讨厌为每个项目编写此实用程序方法。Apache Commons中是否有任何静态方法呢?


32
如果使用标准化单位,则1024应该变成“ 1KiB”,而1024 * 1024应该变成“ 1MiB”。en.wikipedia.org/wiki/Binary_prefix
Pascal Cuoq 2010年

@Pascal:应该有​​几个函数或一个选项来指定基本和单位。
亚伦·迪古拉


3
@Pascal Cuoq:感谢您的参考。直到我读到它,我才意识到,在欧盟,我们必须依法使用正确的前缀。
JeremyP's

2
@DerMike您提到“直到存在这样的库”。现在,这已成为事实。:-) stackoverflow.com/questions/3758606/...
基督教Esken

Answers:


1310

有趣的事实:此处发布的原始代码段是有史以来堆栈溢出中复制最多的Java代码段,并且存在缺陷。它是固定的,但变得凌乱。

本文全文:有史以来复制最多的StackOverflow片段存在缺陷!

来源:将字节大小格式化为人类可读格式 编程指南

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

二进制(1 K = 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());
}

输出示例:

                              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)

12
我更喜欢1.0 KB。然后很明显,输出需要多少有效数字。(例如,这似乎也是duLinux中命令的行为。)
aioobe 2010年

19
我认为每个人都应该注意,在您的项目中,客户希望看到以2为基数(由1024划分)但具有通用前缀的值。不是KiB,MiB,GiB等。请使用KB,MB,GB,TB。
鲍里斯

27
@Borys使用“ KB”表示“ 1024字节”是错误的。不要那样做
endlith 2015年

8
读者将学习它。比犯错误要好一些他们不熟悉并可以学习的东西。写作KB谁是熟悉它的用户会期待1000,谁是不熟悉的用户会期待1024
KAP

16
答案完全重写。以上许多评论已过时。
aioobe

304

FileUtils.byteCountToDisplaySize(long size)如果您的项目可以依靠的话,它将起作用org.apache.commons.io

此方法的JavaDoc


18
我已经在我的项目上使用了commons-io,但是由于舍入行为而最终使用了aioobe的代码(请参阅JavaDoc的链接)
Iravanchi 2012年

3
是否有实用程序可以执行反向操作。从人类可读的字节数中获取字节数?
arunmoezhi15年

6
不幸的是,此功能不支持区域设置。例如,在法语中,它们始终将字节称为“八位字节”,因此,如果您要向法语用户显示100 KB文件,则正确的标签为100 Ko。
塔克罗伊(Tacroy)2015年

@Tacroy您可以在triava库中使用UnitFormatter获取八位字节输出。您可以传递任何单位的字节,瓦数或八位字节。示例,与github.com/trivago/triava中的示例略有修改:UnitFormatter.formatAsUnit(1126,UnitSystem.SI,“ o”); // =“1.13こ”在更多的例子:stackoverflow.com/questions/3758606/...
基督教Esken

5
> 1 gb时,它会四舍五入到最接近的gb,这意味着您获得的精度会有所不同
tksfz

180

使用Android内置类

对于Android,有一个Formatter类。只需一行代码即可完成。

android.text.format.Formatter.formatShortFileSize(activityContext, bytes);

就像formatFileSize(),但是尝试生成更短的数字(显示更少的小数)。

android.text.format.Formatter.formatFileSize(activityContext, bytes);

将内容大小格式化为字节,千字节,兆字节等形式。


12
应该绝对是ANDROID的最佳答案。无需额外的库。+1
节食者

11
我讨厌你必须通过Context
Jared Burrows,2015年

4
绝对应该是ANDROID的最佳答案。
shridutt kothari 2015年

5
您传入Context,以便将其转换为用户当前的语言环境。否则它将不是一个非常有用的功能。
phreakhead '16

7
在知道之前,我一直在使用接受的答案。需要注意的是,在Build.VERSION_CODES.N及更早版本中,使用1024的幂,KB = 1024字节,MB = 1,048,576字节等。从O开始,前缀在SI系统中按其标准含义使用。 ,所以KB = 1000个字节,MB = 1,000,000字节,等等
HendraWD

57

由于单元之间的因数(例如B,KB,MB等)为1024,即2 ^ 10,因此我们可以完全避免使用slow Math.pow()Math.log()method而不会牺牲简单性。该Long班有一个方便的numberOfLeadingZeros(),我们可以用它来判断哪些单元大小值落在方法。

关键点:大小单位之间的距离为10位(1024 = 2 ^ 10),表示最高1位的位置-换句话说,前导零数量相差10(字节= KB * 1024,KB = MB * 1024等)。

前导零的数量与大小单位之间的相关性:

# of leading 0's   Size unit
-------------------------------
>53                B (Bytes)
>43                KB
>33                MB
>23                GB
>13                TB
>3                 PB
<=2                EB

最终代码:

public static String formatSize(long v) {
    if (v < 1024) return v + " B";
    int z = (63 - Long.numberOfLeadingZeros(v)) / 10;
    return String.format("%.1f %sB", (double)v / (1L << (z*10)), " KMGTPE".charAt(z));
}

24

我最近问了同样的问题:

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

尽管没有开箱即用的答案,但我可以接受该解决方案:

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 new DecimalFormat("#,##0.#").format(result) + " " + unit;
}

测试代码:

public static void main(final String[] args){
    final long[] l = new long[] { 1l, 4343l, 43434334l, 3563543743l };
    for(final long ll : l){
        System.out.println(convertToStringRepresentation(ll));
    }
}

输出(在我的德语语言环境中):

1 B
4,2 KB
41,4 MB
3,3 GB

编辑:我已经打开了一个问题,要求为Google Guava提供此功能。也许有人会愿意支持它。


2
为什么0无效的文件大小?
aioobe 2010年

@aioobe这是在我的用例中(显示上传文件的大小),但可以说不是通用的
Sean Patrick Floyd

如果更改最后一行以返回NumberFormat.getFormat(“#,## 0。#”)。format(result)+“” +单位;它也可以在GWT中使用!为此,它仍然不在番石榴中。
汤姆(Tom)2013年

9

这是aioobe的答案的修改版本。

变化:

  • Locale参数,因为某些语言使用.其他语言,作为小数点。
  • 可读代码

private static final String[] SI_UNITS = { "B", "kB", "MB", "GB", "TB", "PB", "EB" };
private static final String[] BINARY_UNITS = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB" };

public static String humanReadableByteCount(final long bytes, final boolean useSIUnits, final Locale locale)
{
    final String[] units = useSIUnits ? SI_UNITS : BINARY_UNITS;
    final int base = useSIUnits ? 1000 : 1024;

    // When using the smallest unit no decimal point is needed, because it's the exact number.
    if (bytes < base) {
        return bytes + " " + units[0];
    }

    final int exponent = (int) (Math.log(bytes) / Math.log(base));
    final String unit = units[exponent];
    return String.format(locale, "%.1f %s", bytes / Math.pow(base, exponent), unit);
}

仅将分隔符符号传递给Locale参数可能会导致结果混合,但不要同时对单元进行本地化以说明对字节也使用不同符号的语言,例如法语。
Nzall

@Nzall你的意思是八位位组吗?维基百科指出它不再常见。其他,您有参考吗?
Christian Strempfer,

7

如果您使用Android,则只需使用android.text.format.Formatter.formatFileSize()即可

替代方案,这是基于此热门帖子的解决方案:

  /**
   * formats the bytes to a human readable format
   *
   * @param si true if each kilo==1000, false if kilo==1024
   */
  @SuppressLint("DefaultLocale")
  public static String humanReadableByteCount(final long bytes,final boolean si)
    {
    final int unit=si ? 1000 : 1024;
    if(bytes<unit)
      return bytes+" B";
    double result=bytes;
    final String unitsToUse=(si ? "k" : "K")+"MGTPE";
    int i=0;
    final int unitsCount=unitsToUse.length();
    while(true)
      {
      result/=unit;
      if(result<unit)
        break;
      // check if we can go further:
      if(i==unitsCount-1)
        break;
      ++i;
      }
    final StringBuilder sb=new StringBuilder(9);
    sb.append(String.format("%.1f ",result));
    sb.append(unitsToUse.charAt(i));
    if(si)
      sb.append('B');
    else sb.append('i').append('B');
    final String resultStr=sb.toString();
    return resultStr;
    }

或在科特林:

/**
 * formats the bytes to a human readable format
 *
 * @param si true if each kilo==1000, false if kilo==1024
 */
@SuppressLint("DefaultLocale")
fun humanReadableByteCount(bytes: Long, si: Boolean): String? {
    val unit = if (si) 1000.0 else 1024.0
    if (bytes < unit)
        return "$bytes B"
    var result = bytes.toDouble()
    val unitsToUse = (if (si) "k" else "K") + "MGTPE"
    var i = 0
    val unitsCount = unitsToUse.length
    while (true) {
        result /= unit
        if (result < unit || i == unitsCount - 1)
            break
        ++i
    }
    return with(StringBuilder(9)) {
        append(String.format("%.1f ", result))
        append(unitsToUse[i])
        if (si) append('B') else append("iB")
    }.toString()
}

您的for循环中似乎有一个错误的错误。我认为应该unitsCount,而不应该unitsCount-1
aioobe 2014年

@aioobe,但这意味着当i == unitsCount时,循环可以停止,这意味着i == 6,这意味着“ charAt”将失败...
android开发者

if(result<unit) break;将在此之前开始。别担心。(如果进行测试,您会注意到您可以完全跳过for循环条件。)
aioobe 2014年

@aioobe正确,这是因为我假设处理“长”变量类型(这是正确的)。另外,它基于这样的假设,即这些单元至少是我写的。如果使用较少的单位,它将产生奇怪的结果(将首选小于1的值,而不是大于1000的值)。
Android开发人员

@aioobe正确。我会修好它。顺便说一句,您的算法也可以提供一个奇怪的结果。尝试将其设置为“ 999999,true”作为参数。它会显示“ 1000.0 kB”,因此它是四舍五入的,但是当人们看到它时,他们会怀疑:为什么它不能显示1MB,因为1000KB = 1MB ...您认为应该如何处理?这是因为String.format,但是我不确定应该如何解决。
android开发人员

6

private static final String[] Q = new String[]{"", "K", "M", "G", "T", "P", "E"};

public String getAsString(long bytes)
{
    for (int i = 6; i > 0; i--)
    {
        double step = Math.pow(1024, i);
        if (bytes > step) return String.format("%3.1f %s", bytes / step, Q[i]);
    }
    return Long.toString(bytes);
}

6
  private String bytesIntoHumanReadable(long bytes) {
        long kilobyte = 1024;
        long megabyte = kilobyte * 1024;
        long gigabyte = megabyte * 1024;
        long terabyte = gigabyte * 1024;

        if ((bytes >= 0) && (bytes < kilobyte)) {
            return bytes + " B";

        } else if ((bytes >= kilobyte) && (bytes < megabyte)) {
            return (bytes / kilobyte) + " KB";

        } else if ((bytes >= megabyte) && (bytes < gigabyte)) {
            return (bytes / megabyte) + " MB";

        } else if ((bytes >= gigabyte) && (bytes < terabyte)) {
            return (bytes / gigabyte) + " GB";

        } else if (bytes >= terabyte) {
            return (bytes / terabyte) + " TB";

        } else {
            return bytes + " Bytes";
        }
    }

我之所以喜欢它,是因为它易于遵循且易于理解。
Joshua Pinter

6

字节单位允许您这样做:

long input1 = 1024;
long input2 = 1024 * 1024;

Assert.assertEquals("1 KiB", BinaryByteUnit.format(input1));
Assert.assertEquals("1 MiB", BinaryByteUnit.format(input2));

Assert.assertEquals("1.024 KB", DecimalByteUnit.format(input1, "#.0"));
Assert.assertEquals("1.049 MB", DecimalByteUnit.format(input2, "#.000"));

NumberFormat format = new DecimalFormat("#.#");
Assert.assertEquals("1 KiB", BinaryByteUnit.format(input1, format));
Assert.assertEquals("1 MiB", BinaryByteUnit.format(input2, format));

我写了另一个库,叫做存储单元,该允许您像这样进行操作:

String formattedUnit1 = StorageUnits.formatAsCommonUnit(input1, "#");
String formattedUnit2 = StorageUnits.formatAsCommonUnit(input2, "#");
String formattedUnit3 = StorageUnits.formatAsBinaryUnit(input1);
String formattedUnit4 = StorageUnits.formatAsBinaryUnit(input2);
String formattedUnit5 = StorageUnits.formatAsDecimalUnit(input1, "#.00", Locale.GERMAN);
String formattedUnit6 = StorageUnits.formatAsDecimalUnit(input2, "#.00", Locale.GERMAN);
String formattedUnit7 = StorageUnits.formatAsBinaryUnit(input1, format);
String formattedUnit8 = StorageUnits.formatAsBinaryUnit(input2, format);

Assert.assertEquals("1 kB", formattedUnit1);
Assert.assertEquals("1 MB", formattedUnit2);
Assert.assertEquals("1.00 KiB", formattedUnit3);
Assert.assertEquals("1.00 MiB", formattedUnit4);
Assert.assertEquals("1,02 kB", formattedUnit5);
Assert.assertEquals("1,05 MB", formattedUnit6);
Assert.assertEquals("1 KiB", formattedUnit7);
Assert.assertEquals("1 MiB", formattedUnit8);

如果您要强制某个单位,请执行以下操作:

String formattedUnit9 = StorageUnits.formatAsKibibyte(input2);
String formattedUnit10 = StorageUnits.formatAsCommonMegabyte(input2);

Assert.assertEquals("1024.00 KiB", formattedUnit9);
Assert.assertEquals("1.00 MB", formattedUnit10);

5
    public static String floatForm (double d)
    {
       return new DecimalFormat("#.##").format(d);
    }


    public static String bytesToHuman (long size)
    {
        long Kb = 1  * 1024;
        long Mb = Kb * 1024;
        long Gb = Mb * 1024;
        long Tb = Gb * 1024;
        long Pb = Tb * 1024;
        long Eb = Pb * 1024;

        if (size <  Kb)                 return floatForm(        size     ) + " byte";
        if (size >= Kb && size < Mb)    return floatForm((double)size / Kb) + " Kb";
        if (size >= Mb && size < Gb)    return floatForm((double)size / Mb) + " Mb";
        if (size >= Gb && size < Tb)    return floatForm((double)size / Gb) + " Gb";
        if (size >= Tb && size < Pb)    return floatForm((double)size / Tb) + " Tb";
        if (size >= Pb && size < Eb)    return floatForm((double)size / Pb) + " Pb";
        if (size >= Eb)                 return floatForm((double)size / Eb) + " Eb";

        return "???";
    }

3

现在有一个包含单位格式的库。我将其添加到triava库中,因为似乎只有其他现有的库适用于Android。

它可以在3种不同的系统(SI,IEC,JEDEC)和各种输出选项中以任意精度格式化数字。这是triava单元测试中的一些代码示例:

UnitFormatter.formatAsUnit(1126, UnitSystem.SI, "B");
// = "1.13kB"
UnitFormatter.formatAsUnit(2094, UnitSystem.IEC, "B");
// = "2.04KiB"

打印精确的千克,兆值(此处W =瓦特):

UnitFormatter.formatAsUnits(12_000_678, UnitSystem.SI, "W", ", ");
// = "12MW, 678W"

您可以传递DecimalFormat来定制输出:

UnitFormatter.formatAsUnit(2085, UnitSystem.IEC, "B", new DecimalFormat("0.0000"));
// = "2.0361KiB"

对于千或兆值的任意运算,您可以将它们分为几个部分:

UnitComponent uc = new  UnitComponent(123_345_567_789L, UnitSystem.SI);
int kilos = uc.kilo(); // 567
int gigas = uc.giga(); // 123

2

我知道更新此帖子为时已晚!但是我对此很开心:

创建一个接口:

public interface IUnits {
     public String format(long size, String pattern);
     public long getUnitSize();
}

创建StorageUnits类:

import java.text.DecimalFormat;

public class StorageUnits {
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;

enum Unit implements IUnits {
    TERA_BYTE {
        @Override
        public String format(long size, String pattern) {
            return format(size, getUnitSize(), "TB", pattern);
        }
        @Override
        public long getUnitSize() {
            return T;
        }
        @Override
        public String toString() {
            return "Terabytes";
        }
    },
    GIGA_BYTE {
        @Override
        public String format(long size, String pattern) {
            return format(size, getUnitSize(), "GB", pattern);
        }
        @Override
        public long getUnitSize() {
            return G;
        }
        @Override
        public String toString() {
            return "Gigabytes";
        }
    },
    MEGA_BYTE {
        @Override
        public String format(long size, String pattern) {
            return format(size, getUnitSize(), "MB", pattern);
        }
        @Override
        public long getUnitSize() {
            return M;
        }
        @Override
        public String toString() {
            return "Megabytes";
        }
    },
    KILO_BYTE {
        @Override
        public String format(long size, String pattern) {
            return format(size, getUnitSize(), "kB", pattern);
        }
        @Override
        public long getUnitSize() {
            return K;
        }
        @Override
        public String toString() {
            return "Kilobytes";
        }

    };
    String format(long size, long base, String unit, String pattern) {
        return new DecimalFormat(pattern).format(
                Long.valueOf(size).doubleValue() / Long.valueOf(base).doubleValue()
        ) + unit;
    }
}

public static String format(long size, String pattern) {
    for(Unit unit : Unit.values()) {
        if(size >= unit.getUnitSize()) {
            return unit.format(size, pattern);
        }
    }
    return ("???(" + size + ")???");
}

public static String format(long size) {
    return format(size, "#,##0.#");
}
}

称它为:

class Main {
    public static void main(String... args) {
         System.out.println(StorageUnits.format(21885));
         System.out.println(StorageUnits.format(2188121545L));
    }
}

输出:

21.4kB
2GB

2

在不大可能的情况下,它可以节省一些时间,或者只是为好玩而已,这是Go版本。为简单起见,我只包括了二进制输出的情况。

func sizeOf(bytes int64) string {
    const unit = 1024
    if bytes < unit {
        return fmt.Sprintf("%d B", bytes)
    }

    fb := float64(bytes)
    exp := int(math.Log(fb) / math.Log(unit))
    pre := "KMGTPE"[exp-1]
    div := math.Pow(unit, float64(exp))
    return fmt.Sprintf("%.1f %ciB", fb / div, pre)
}

1
String[] fileSizeUnits = {"bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
public String calculateProperFileSize(double bytes){
    String sizeToReturn = "";
    int index = 0;
    for(index = 0; index < fileSizeUnits.length; index++){
        if(bytes < 1024){
            break;
        }
        bytes = bytes / 1024;
    }

只需添加更多文件单元(如果缺少),您将看到达到该单元的单元大小(如果您的文件有那么长)System.out.println(“文件大小以正确的格式:” +字节+“” + fileSizeUnits [指数]); sizeToReturn = String.valueOf(bytes)+“” + fileSizeUnits [index]; return sizeToReturn; }


1

这是上述Java正确共识答案的C#.net等效项。(下面还有另一个代码较短的代码)

    public static String BytesNumberToHumanReadableString(long bytes, bool SI1000orBinary1024)
    {

        int unit = SI1000orBinary1024 ? 1000 : 1024;
        if (bytes < unit) return bytes + " B";
        int exp = (int)(Math.Log(bytes) / Math.Log(unit));
        String pre = (SI1000orBinary1024 ? "kMGTPE" : "KMGTPE")[(exp - 1)] + (SI1000orBinary1024 ? "" : "i");
        return String.Format("{0:F1} {1}B", bytes / Math.Pow(unit, exp), pre);
    }

从技术上讲,如果我们坚持使用SI单位,则此例程适用于任何常规的数字使用。专家还有许多其他好的答案。假设您正在对gridview上的数字进行数据绑定,那么值得从它们中检查性能优化的例程。

PS:发布是因为在我执行C#项目时,此问题/答案在Google搜索中排在首位。


1

您可以使用StringUtilsTraditionalBinarPrefix

public static String humanReadableInt(long number) {
    return TraditionalBinaryPrefix.long2String(number,””,1);
}

1

有点旧了,但是,... org.springframework.util.unit.DataSize至少可以满足此要求,然后进行简单的装饰即可



0

您是否尝试过JSR 363?它的单元扩展模块(如Unicode CLDR)(在GitHub:uom-systems中)可为您完成所有这些工作。

您可以MetricPrefix在每个实现中使用或BinaryPrefix(与上述示例类似),如果您在印度或附近国家IndianPrefix(例如,在uom-systems的通用模块中)生活和工作,则可以使用和格式化“ Crore字节”或“拉赫字节”。


0

也许您可以使用以下代码(在C#中):

        long Kb = 1024;
        long Mb = Kb * 1024;
        long Gb = Mb * 1024;
        long Tb = Gb * 1024;
        long Pb = Tb * 1024;
        long Eb = Pb * 1024;

        if (size < Kb) return size.ToString() + " byte";
        if (size < Mb) return (size / Kb).ToString("###.##") + " Kb.";
        if (size < Gb) return (size / Mb).ToString("###.##") + " Mb.";
        if (size < Tb) return (size / Gb).ToString("###.##") + " Gb.";
        if (size < Pb) return (size / Tb).ToString("###.##") + " Tb.";
        if (size < Eb) return (size / Pb).ToString("###.##") + " Pb.";
        if (size >= Eb) return (size / Eb).ToString("###.##") + " Eb.";

        return "invalid size";

0
public String humanReadable(long size) {
    long limit = 10 * 1024;
    long limit2 = limit * 2 - 1;
    String negative = "";
    if(size < 0) {
        negative = "-";
        size = Math.abs(size);
    }

    if(size < limit) {
        return String.format("%s%s bytes", negative, size);
    } else {
        size = Math.round((double) size / 1024);
        if (size < limit2) {
            return String.format("%s%s kB", negative, size);
        } else {
            size = Math.round((double)size / 1024);
            if (size < limit2) {
                return String.format("%s%s MB", negative, size);
            } else {
                size = Math.round((double)size / 1024);
                if (size < limit2) {
                    return String.format("%s%s GB", negative, size);
                } else {
                    size = Math.round((double)size / 1024);
                        return String.format("%s%s TB", negative, size);
                }
            }
        }
    }
}

0

使用以下功能获取确切的信息,这些信息是通过ATM_CashWithdrawl概念基础生成的。

getFullMemoryUnit(): Total: [123 MB], Max: [1 GB, 773 MB, 512 KB], Free: [120 MB, 409 KB, 304 Bytes]
public static String getFullMemoryUnit(long unit) {
    long BYTE = 1024, KB = BYTE, MB = KB * KB, GB = MB * KB, TB = GB * KB;
    long KILO_BYTE, MEGA_BYTE = 0, GIGA_BYTE = 0, TERA_BYTE = 0;
    unit = Math.abs(unit);
    StringBuffer buffer = new StringBuffer();
    if ( unit / TB > 0 ) {
        TERA_BYTE = (int) (unit / TB);
        buffer.append(TERA_BYTE+" TB");
        unit -= TERA_BYTE * TB;
    }
    if ( unit / GB > 0 ) {
        GIGA_BYTE = (int) (unit / GB);
        if (TERA_BYTE != 0) buffer.append(", ");
        buffer.append(GIGA_BYTE+" GB");
        unit %= GB;
    }
    if ( unit / MB > 0 ) {
        MEGA_BYTE = (int) (unit / MB);
        if (GIGA_BYTE != 0) buffer.append(", ");
        buffer.append(MEGA_BYTE+" MB");
        unit %= MB;
    }
    if ( unit / KB > 0 ) {
        KILO_BYTE = (int) (unit / KB);
        if (MEGA_BYTE != 0) buffer.append(", ");
        buffer.append(KILO_BYTE+" KB");
        unit %= KB;
    }
    if ( unit > 0 ) buffer.append(", "+unit+" Bytes");
    return buffer.toString();
}

我刚刚修改了facebookarchive-StringUtils的代码,以获取以下格式。使用apache.hadoop-时将获得相同的格式StringUtils

getMemoryUnit(): Total: [123.0 MB], Max: [1.8 GB], Free: [120.4 MB]
public static String getMemoryUnit(long bytes) {
    DecimalFormat oneDecimal = new DecimalFormat("0.0");
    float BYTE = 1024.0f, KB = BYTE, MB = KB * KB, GB = MB * KB, TB = GB * KB;
    long absNumber = Math.abs(bytes);
    double result = bytes;
    String suffix = " Bytes";
    if (absNumber < MB) {
        result = bytes / KB;
        suffix = " KB";
    } else if (absNumber < GB) {
        result = bytes / MB;
        suffix = " MB";
    } else if (absNumber < TB) {
        result = bytes / GB;
        suffix = " GB";
    }
    return oneDecimal.format(result) + suffix;
}

上述方法的用法示例:

public static void main(String[] args) {
    Runtime runtime = Runtime.getRuntime();
    int availableProcessors = runtime.availableProcessors();

    long heapSize = Runtime.getRuntime().totalMemory(); 
    long heapMaxSize = Runtime.getRuntime().maxMemory();
    long heapFreeSize = Runtime.getRuntime().freeMemory();

    System.out.format("Total: [%s], Max: [%s], Free: [%s]\n", heapSize, heapMaxSize, heapFreeSize);
    System.out.format("getMemoryUnit(): Total: [%s], Max: [%s], Free: [%s]\n",
            getMemoryUnit(heapSize), getMemoryUnit(heapMaxSize), getMemoryUnit(heapFreeSize));
    System.out.format("getFullMemoryUnit(): Total: [%s], Max: [%s], Free: [%s]\n",
            getFullMemoryUnit(heapSize), getFullMemoryUnit(heapMaxSize), getFullMemoryUnit(heapFreeSize));
}

获得以上格式的字节

Total: [128974848], Max: [1884815360], Free: [126248240]

为了以人类可读的格式显示时间,请使用此功能millisToShortDHMS(long duration)


0

这是从@aioobe转换为kotlin的转换

/**
 * https://stackoverflow.com/a/3758880/1006741
 */
fun Long.humanReadableByteCountBinary(): String {
    val b = when (this) {
        Long.MIN_VALUE -> Long.MAX_VALUE
        else -> abs(this)
    }
    return when {
        b < 1024L -> "$this B"
        b <= 0xfffccccccccccccL shr 40 -> "%.1f KiB".format(Locale.UK, this / 1024.0)
        b <= 0xfffccccccccccccL shr 30 -> "%.1f MiB".format(Locale.UK, this / 1048576.0)
        b <= 0xfffccccccccccccL shr 20 -> "%.1f GiB".format(Locale.UK, this / 1.073741824E9)
        b <= 0xfffccccccccccccL shr 10 -> "%.1f TiB".format(Locale.UK, this / 1.099511627776E12)
        b <= 0xfffccccccccccccL -> "%.1f PiB".format(Locale.UK, (this shr 10) / 1.099511627776E12)
        else -> "%.1f EiB".format(Locale.UK, (this shr 20) / 1.099511627776E12)
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.