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

比如1024应该变成“1 Kb”,1024*1024应该变成“1 Mb”。

我有点厌倦了为每个项目写这个实用方法。在Apache Commons中有这样的静态方法吗?


当前回答

datasize至少在计算中可以满足这个需求。那么一个简单的装饰器就可以了。

其他回答

如果在Android上,你可以简单地调用Android .text. format . formatter的一个静态方法。

https://developer.android.com/reference/android/text/format/Formatter

下面是上面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);
    }

从技术上讲,如果我们坚持使用国际单位制,这个程序适用于任何常规的数字使用。专家们还给出了许多不错的答案。假设您正在对gridview上的数字进行数据绑定,有必要从它们中查看性能优化例程。

PS:这个帖子是因为当我在做一个c#项目时,这个问题/答案出现在谷歌搜索的顶部。

使用下面的函数来获得确切的信息。它是基于atm_cashwithdraw概念生成的。

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(长持续时间)。


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

下面是一个快速,简单和可读的代码片段来实现这一点:

/**
 * Converts byte size to human readable strings (also declares useful constants)
 *
 * @see <a href="https://en.wikipedia.org/wiki/File_size">File size</a>
 */
@SuppressWarnings("SpellCheckingInspection")
public class HumanReadableSize {
    public static final double
            KILO = 1000L, // 1000 power 1 (10 power 3)
            KIBI = 1024L, // 1024 power 1 (2 power 10)
            MEGA = KILO * KILO, // 1000 power 2 (10 power 6)
            MEBI = KIBI * KIBI, // 1024 power 2 (2 power 20)
            GIGA = MEGA * KILO, // 1000 power 3 (10 power 9)
            GIBI = MEBI * KIBI, // 1024 power 3 (2 power 30)
            TERA = GIGA * KILO, // 1000 power 4 (10 power 12)
            TEBI = GIBI * KIBI, // 1024 power 4 (2 power 40)
            PETA = TERA * KILO, // 1000 power 5 (10 power 15)
            PEBI = TEBI * KIBI, // 1024 power 5 (2 power 50)
            EXA = PETA * KILO, // 1000 power 6 (10 power 18)
            EXBI = PEBI * KIBI; // 1024 power 6 (2 power 60)

    private static final DecimalFormat df = new DecimalFormat("#.##");

    public static String binaryBased(long size) {
        if (size < 0) {
            throw new IllegalArgumentException("Argument cannot be negative");
        } else if (size < KIBI) {
            return df.format(size).concat("B");
        } else if (size < MEBI) {
            return df.format(size / KIBI).concat("KiB");
        } else if (size < GIBI) {
            return df.format(size / MEBI).concat("MiB");
        } else if (size < TEBI) {
            return df.format(size / GIBI).concat("GiB");
        } else if (size < PEBI) {
            return df.format(size / TEBI).concat("TiB");
        } else if (size < EXBI) {
            return df.format(size / PEBI).concat("PiB");
        } else {
            return df.format(size / EXBI).concat("EiB");
        }
    }

    public static String decimalBased(long size) {
        if (size < 0) {
            throw new IllegalArgumentException("Argument cannot be negative");
        } else if (size < KILO) {
            return df.format(size).concat("B");
        } else if (size < MEGA) {
            return df.format(size / KILO).concat("KB");
        } else if (size < GIGA) {
            return df.format(size / MEGA).concat("MB");
        } else if (size < TERA) {
            return df.format(size / GIGA).concat("GB");
        } else if (size < PETA) {
            return df.format(size / TERA).concat("TB");
        } else if (size < EXA) {
            return df.format(size / PETA).concat("PB");
        } else {
            return df.format(size / EXA).concat("EB");
        }
    }
}

注意:

上面的代码冗长而简单。 它不使用循环(循环应该只在您不知道在编译期间需要迭代多少次时使用) 它不会进行不必要的库调用(StringBuilder, Math等) 上面的代码是快速的,使用非常少的内存。基于在我个人的入门级云计算机上运行的基准测试,它是最快的(在这些情况下性能并不重要,但仍然如此) 以上代码是一个很好的答案的修改版本