代码之家  ›  专栏  ›  技术社区  ›  Igor Mukhin

如何在java中把字节大小转换成可读的格式?

  •  475
  • Igor Mukhin  · 技术社区  · 14 年前

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

    22 回复  |  直到 5 年前
        1
  •  1374
  •   ivan_pozdeev RenanSS    4 年前

    有趣的事实:

    本文的全部内容: The most copied Stack Overflow snippet of all time is flawed!

    资料来源: Formatting byte size to human readable format | Programming.Guide

    国际单位制(1 k=1000)

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

    二进制(1ki=1024)

    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)
    
        2
  •  327
  •   Zarathustra    9 年前

    FileUtils.byteCountToDisplaySize(long size) 如果你的项目可以依靠 org.apache.commons.io .

    JavaDoc for this method

        3
  •  195
  •   Peter Mortensen icecrime    5 年前

    使用Android内置类

    格式化程序

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

    就像 formatFileSize()

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

        4
  •  65
  •   icza    5 年前

    我们完全可以避免使用慢 Math.pow() Math.log() 方法不牺牲简单性,因为单位之间的因子(例如,B、KB、MB等)是1024,即2^10。这个 Long numberOfLeadingZeros() 方法,我们可以使用它来判断大小值属于哪个单位。

    重点: 大小单位的距离为10位(1024=2^10),表示最高一位的位置,或者换句话说 前导零数 相差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));
    }
    
        5
  •  26
  •   Peter Mortensen icecrime    5 年前

    我最近也问了同样的问题:

    Format file size as MB, GB, etc.

    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
    

    我开了一家 issue requesting this functionality for Google Guava . 也许有人会愿意支持它。

        6
  •  11
  •   Peter Mortensen icecrime    5 年前
    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";
        }
    }
    
        7
  •  9
  •   Community CDub    8 年前

    这是的修改版本 aioobe's answer .

    • 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);
    }
    
        8
  •  7
  •   Lars Bohl    14 年前
    
    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);
    }
    
        9
  •  7
  •   Sebastian Hoß    9 年前

    Byte Units 允许您这样做:

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

    我写了另一个图书馆叫 storage-units 你可以这样做:

    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);
    
        10
  •  6
  •   Peter Mortensen icecrime    5 年前

    如果你使用Android,你可以简单地使用 android.text.format.Formatter.formatFileSize()

    或者,这里有一个基于 this popular post

      /**
       * 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()
    }
    
        11
  •  5
  •   XXX    11 年前
        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 "???";
        }
    
        12
  •  3
  •   Christian Esken    9 年前

    triava

    它可以在3种不同的系统(SI、IEC、JEDEC)和各种输出选项中以任意精度格式化数字。下面是 triava unit tests

    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"
    

    对于kilo或mega值的任意操作,可以将其拆分为以下组件:

    UnitComponent uc = new  UnitComponent(123_345_567_789L, UnitSystem.SI);
    int kilos = uc.kilo(); // 567
    int gigas = uc.giga(); // 123
    
        13
  •  3
  •   Peter Mortensen icecrime    5 年前

    org.springframework.util文件.单位.数据大小至少在计算上可以满足这个要求。那么一个简单的装饰师就可以了。

        14
  •  2
  •   Peter Mortensen icecrime    5 年前

    创建接口:

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

    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
    
        15
  •  2
  •   aminography    4 年前

    • Kotlin Version 通过 Extension Property

    如果您正在使用 kotlin


    HumanizeUtils.kt

    import java.io.File
    import kotlin.math.log2
    import kotlin.math.pow
    
    /**
     * @author aminography
     */
    
    val File.formatSize: String
        get() = length().formatAsFileSize
    
    val Int.formatAsFileSize: String
        get() = toLong().formatAsFileSize
    
    val Long.formatAsFileSize: String
        get() = log2(if (this != 0L) toDouble() else 1.0).toInt().div(10).let {
            val precision = when (it) {
                0 -> 0; 1 -> 1; else -> 2
            }
            val prefix = arrayOf("", "K", "M", "G", "T", "P", "E", "Z", "Y")
            String.format("%.${precision}f ${prefix[it]}B", toDouble() / 2.0.pow(it * 10.0))
        }
    

    用法:

    println("0:          " + 0.formatAsFileSize)
    println("170:        " + 170.formatAsFileSize)
    println("14356:      " + 14356.formatAsFileSize)
    println("968542985:  " + 968542985.formatAsFileSize)
    println("8729842496: " + 8729842496.formatAsFileSize)
    
    println("file: " + file.formatSize)
    

    0:          0 B
    170:        170 B
    14356:      14.0 KB
    968542985:  923.67 MB
    8729842496: 8.13 GB
    
    file: 6.15 MB
    
        16
  •  1
  •   Peter Mortensen icecrime    5 年前

    下面是C#.NET等价于Java的正确答案 (下面的另一个代码较短):

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

    PS:这是因为我在做一个C项目时,这个问题/答案出现在谷歌搜索的最上面。

        17
  •  1
  •   Peter Mortensen icecrime    5 年前

    StringUtils s码 TraditionalBinarPrefix :

    public static String humanReadableInt(long number) {
        return TraditionalBinaryPrefix.long2String(number, ””, 1);
    }
    
        18
  •  1
  •   Peter Mortensen icecrime    5 年前

    也许你可以用这个代码(用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";
    
        19
  •  1
  •   Peter Mortensen icecrime    5 年前

    这里有一个 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)
    }
    
        20
  •  1
  •   Peter Mortensen icecrime    5 年前

    the conversion from 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)
        }
    }
    
        21
  •  1
  •   Vishwajit R. Shinde    5 年前
    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("File size in proper format: " + bytes + " " + fileSizeUnits[index]);
        sizeToReturn = String.valueOf(bytes) + " " + fileSizeUnits[index];
        return sizeToReturn;
    }
    

    只需添加更多的文件单元(如果缺少),您将看到单元大小达到该单元(如果您的文件有那么长):

        22
  •  1
  •   i30mb1    4 年前

    我使用的是比公认的答案稍加修改的方法:

    public static String formatFileSize(long bytes) {
            if (bytes <= 0) return "";
            if (bytes < 1000) return bytes + " B";
            CharacterIterator ci = new StringCharacterIterator("kMGTPE");
            while (bytes >= 99_999) {
                bytes /= 1000;
                ci.next();
            }
            return String.format(Locale.getDefault(), "%.1f %cB", bytes / 1000.0, ci.current());
        }
    

    因为我想看到另一个输出:

                                  SI   
    
                       0:            <--------- instead of 0 B
                      27:       27 B     
                     999:      999 B   
                    1000:     1.0 kB   
                    1023:     1.0 kB   
                    1024:     1.0 kB 
                    1728:     1.7 kB   
                  110592:     0.1 MB <--------- instead of 110.6 kB
                 7077888:     7.1 MB  
               452984832:     0.5 GB <--------- instead of 453.0 MB
             28991029248:    29.0 GB  
    
        23
  •  0
  •   Samkov Max    6 年前
    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);
                    }
                }
            }
        }
    }
    
        24
  •  0
  •   Peter Mortensen icecrime    5 年前

    使用以下函数可以获得准确的信息。它是以 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)

        25
  •  0
  •   Peter Mortensen icecrime    5 年前

    尝试 JSR 363 . 它的单元扩展模块,如Unicode CLDR(in GitHub: uom-systems )为你做这一切。

    MetricPrefix BinaryPrefix (与上面的一些例子类似)如果你在印度或附近的国家生活和工作, IndianPrefix (同样在计量单位系统的公共模块中)也允许您使用和格式化“百万字节”或“十万字节”。

        26
  •  0
  •   Forcuti Alessandro    4 年前

    public static String getFileSize(double size) {
        return _getFileSize(size,0,1024);
    }
    
    public static String _getFileSize(double size, int i, double base) {
        String units = " KMGTP";
        String unit = (i>0)?(""+units.charAt(i)).toUpperCase()+"i":"";
        if(size<base)
            return size +" "+unit.trim()+"B";
        else {
            size = Math.floor(size/base);
            return _getFileSize(size,++i,base);
        }
    }
    
        27
  •  0
  •   Manu Manjunath    4 年前

    下面是一个快速、简单且可读的代码段,可以实现这一点:

    /**
     * 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");
            }
        }
    }
    

    1. 上面的代码冗长而直接。
      • 是的 使用循环(仅当不知道编译期间需要迭代多少次时才应使用循环)
      • StringBuilder , Math 等等)
    2. 上面的代码是一个很好的答案之一的修改版本
        28
  •  -1
  •   benka Csaba    11 年前
    filename=filedilg.getSelectedFile().getAbsolutePath();
    File file=new File(filename);
    
    String disp=FileUtils.byteCountToDisplaySize(file.length());
    System.out.println("THE FILE PATH IS "+file+"THIS File SIZE IS IN MB "+disp);