जावा में बाइट आकार को मानव पठनीय प्रारूप में कैसे बदलें?


556

जावा में बाइट आकार को मानव-पठनीय प्रारूप में कैसे परिवर्तित किया जाए? जैसे 1024 "1 Kb" बनना चाहिए और 1024 * 1024 "1 एमबी" बनना चाहिए।

मैं प्रत्येक परियोजना के लिए इस उपयोगिता विधि को लिखने के लिए बीमार हूँ। क्या इसके लिए Apache Commons में कोई स्थैतिक विधियाँ हैं ?


32
यदि आप मानकीकृत इकाइयों का उपयोग करते हैं, तो 1024 को "1KiB" और 1024 * 1024 का "1MiB" बनना चाहिए। en.wikipedia.org/wiki/Binary_prefix
पास्कल क्यूक सिप

@ पास्कल: आधार और यूनिट को निर्दिष्ट करने के लिए कई कार्य या एक विकल्प होना चाहिए।
एरोन दिगुल्ला


3
@ पास्कल कूक: संदर्भ के लिए धन्यवाद। मुझे तब तक एहसास नहीं हुआ जब तक मैंने यह नहीं पढ़ा कि यहाँ यूरोपीय संघ में हमें कानून द्वारा सही उपसर्गों का उपयोग करना आवश्यक है।
जेरेमीपप

2
@DerMike आपने उल्लेख किया कि "जब तक इस तरह की लाइब्रेरी मौजूद है"। यह अब सच हो गया है। :-) stackoverflow.com/questions/3758606/…
क्रिश्चियन Esken

जवाबों:


1310

मजेदार तथ्य: यहां पोस्ट की गई मूल स्निपेट स्टैक ओवरफ्लो पर सभी समय का सबसे अधिक कॉपी किया गया जावा स्निपेट था, और यह त्रुटिपूर्ण था। यह तय था लेकिन यह गड़बड़ हो गया।

इस लेख में पूरी कहानी: सभी समय का सबसे कॉपी किया गया स्टैकऑवरफ्लो स्निपेट त्रुटिपूर्ण है!

स्रोत: मानव पठनीय प्रारूप के लिए बाइट आकार स्वरूपण | Programming.Guide

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 के = 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 पसंद है। फिर यह स्पष्ट है कि आउटपुट कितने महत्वपूर्ण आंकड़े देता है। (यह duलिनक्स में कमांड के उदाहरण के लिए व्यवहार भी प्रतीत होता है ।)
aioobe

19
मुझे लगता है कि हर एक को यह ध्यान रखना चाहिए कि आपके प्रोजेक्ट में ग्राहक बेस 2 (1024 के आधार पर) में मान देखना चाहते हैं लेकिन सामान्य उपसर्ग के साथ। नहीं KiB, MiB, GiB आदि इसके लिए KB, MB, GB, TB का उपयोग करें।
बोरिस

27
@ बायरी "KB" का उपयोग करने के लिए "1024 बाइट्स" का अर्थ गलत है। ऐसा मत करो।
एंडोलिथ

8
पाठक इसे सीखेंगे। बेहतर है कि वे किसी चीज से अपरिचित हों और कुछ गलत होने से सीख सकते हैं। KB लिखने वाले एक उपयोगकर्ता जो इसके साथ परिचित है, वह 1000 की उम्मीद करेगा और अपरिचित एक उपयोगकर्ता 1024 की उम्मीद करेगा।
kap

16
जवाब पूरी तरह से फिर से लिखा। उपरोक्त टिप्पणियों में से कई अप्रचलित हैं।
ऐयोबेब

304

FileUtils.byteCountToDisplaySize(long size)अगर आपका प्रोजेक्ट निर्भर हो सकता है तो काम करेगा org.apache.commons.io

इस विधि के लिए JavaDoc


18
मेरे पास पहले से ही मेरी परियोजना पर कॉमन्स-आईआईओ है, लेकिन राउंडिंग व्यवहार (
जावाडॉक के

3
क्या रिवर्स ऑपरेशन करने की उपयोगिता है। मानव पठनीय बाइट गिनती से बाइट गिनती?
अरुणमोझी

6
दुर्भाग्य से यह फ़ंक्शन स्थानीय-जागरूक नहीं है; फ्रांसीसी में, उदाहरण के लिए, वे हमेशा बाइट्स को "ओकटेट" कहते हैं, इसलिए यदि आप किसी फ्रांसीसी उपयोगकर्ता को 100 केबी फ़ाइल प्रदर्शित करने जा रहे हैं, तो सही लेबल 100 Ko होगा।
ताकारॉय

@ टैकोरॉय आप ट्रायवा लाइब्रेरी में UnitFormatter के साथ ऑक्टेट आउटपुट प्राप्त कर सकते हैं। आप बाइट्स, वाट्स या ऑक्टेट के लिए किसी भी यूनिट को पास कर सकते हैं। उदाहरण, github.com/trivago/triava में उदाहरणों से थोड़ा संशोधित : UnitFormatter.formatAsUnit (1126, UnitSystem.SI, "o"); // = "1.13 ko" अधिक उदाहरण: stackoverflow.com/questions/3758606/…
क्रिश्चियन Esken

5
यह निकटतम gb में तब
पहुंचता है

180

Android अंतर्निहित वर्ग का उपयोग करें

Android के लिए एक क्लास फॉर्मैटर है । कोड की सिर्फ एक पंक्ति और आप कर रहे हैं।

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

यह पसंद है formatFileSize(), लेकिन कम संख्या (कम दशमलव दिखा) उत्पन्न करने की कोशिश कर रहा है।

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

एक सामग्री का आकार बाइट्स, किलोबाइट, मेगाबाइट, आदि के रूप में होना चाहिए।


12
निश्चित रूप से ANDROID के लिए सबसे अच्छा उत्तर होना चाहिए। कोई अतिरिक्त पुस्तकालयों की जरूरत है। +1
डायटर

11
मुझे इस तथ्य से नफरत है कि आपको इसमें पास होना है Context
जेरेड बरोज

4
निश्चित रूप से ANDROID के लिए सबसे अच्छा उत्तर होना चाहिए।
श्रीदत्त कोठारी

5
आप संदर्भ में गुजरते हैं, इसलिए इसका उपयोगकर्ता के वर्तमान स्थान में अनुवाद किया जाता है। अन्यथा यह बहुत उपयोगी कार्य नहीं होगा।
फ्राकहेड

7
इससे पहले कि मैं यह जानता हूं मैं स्वीकृत उत्तर का उपयोग कर रहा था। बस ध्यान दिया जाना चाहिए, Build.VERSION_CODES.N और पहले में, 1024 की शक्तियों का उपयोग KB = 1024 बाइट्स, MB = 1,048,576 बाइट्स, आदि के साथ किया जाता है। O के रूप में, उपसर्गों का उपयोग SI सिस्टम में उनके मानक अर्थों में किया जाता है। , इसलिए kB = 1000 बाइट्स, MB = 1,000,000 बाइट्स, आदि
HendraWD

57

हम इकाइयों के बीच के कारक (जैसे बी, केबी, एमबी आदि) के बाद से सादगी का त्याग किए बिना धीमी Math.pow()और Math.log()विधियों का उपयोग करने से पूरी तरह से बच सकते हैं जो 1024 है जो 2 ^ 10 है। 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 अमरूद के लिए इस कार्यक्षमता का अनुरोध करते हुए एक मुद्दा खोला है । शायद कोई इसका समर्थन करना चाहेगा।


2
0 एक अमान्य फ़ाइल-आकार क्यों है?
aioobe

@aioobe यह मेरे उपयोग के मामले में था (अपलोड की गई फ़ाइल का आकार प्रदर्शित करना), लेकिन यकीनन यह सार्वभौमिक नहीं है
सीन पैट्रिक फ्लोयड

यदि आप NumberFormat.getFormat ("#, ## 0। #") को वापस करने के लिए अंतिम पंक्ति को बदलते हैं। स्वरूप (परिणाम) + "" + इकाई; यह GWT में भी काम करता है! इसके लिए धन्यवाद, यह अभी भी अमरूद में नहीं है।
टॉम

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

यह विभाजक प्रतीकों के लिए एक लोकेल पैरामीटर के साथ पास करने के लिए थोड़ा मिश्रित परिणाम है, लेकिन फिर उन इकाइयों के लिए भी स्थानीयकरण न करें जो फ्रेंच की तरह बाइट्स के लिए एक अलग प्रतीक का उपयोग करते हैं।
नजल्ल

@Nzall आप ऑक्टेट मतलब है? विकिपीडिया कह रहा है कि यह अब आम नहीं है। और, क्या आपके पास एक संदर्भ है?
क्रिश्चियन स्ट्रेम्पफर

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

आपको अपने फॉर-लूप में ऑफ-बाय-वन एरर लगता है। मुझे लगता है कि यह होना चाहिए unitsCountऔर नहीं unitsCount-1
aioobe

@ आईओबी लेकिन इसका मतलब है कि लूप बंद हो सकता है जब मैं == यूनिट्सकाउंट, जिसका अर्थ है मैं == 6, जिसका अर्थ है "चार्ट" विफल हो जाएगा ...
Android डेवलपर

if(result<unit) break;उससे पहले किक करेंगे। कोई चिंता नहीं। (यदि आप इसका परीक्षण करते हैं, तो आप देखेंगे कि आप पूरी तरह से लूप की स्थिति को छोड़ सकते हैं।)
aioobe

@aioobe सही, यह धारणा (जो सही है) के कारण है कि मैं "लंबे" चर प्रकार को संभालता हूं। इसके अलावा, यह इस धारणा पर आधारित है कि इकाइयां कम से कम मैंने क्या लिखा है। यदि आप कम इकाइयों का उपयोग करते हैं, तो यह अजीब परिणाम देगा (बड़े-से-1000 मूल्यों के बजाय कम-से-कम 1 मूल्यों को प्राथमिकता देगा)।
एंड्रॉयड डेवलपर

@aioobe सही। मैं इसे ठीक कर दूंगा। BTW, आपका एल्गोरिथ्म भी एक अजीब परिणाम प्रदान कर सकता है। तर्कों के रूप में इसे "999999, सच" देने का प्रयास करें। यह "1000.0 kB" दिखाएगा, इसलिए यह गोल है, लेकिन जब लोग इसे देखते हैं, तो वे आश्चर्यचकित हो सकते हैं: यह 1MB, 1000KB = 1MB के रूप में क्यों नहीं दिखा सकता है ... आपको क्या लगता है कि इसे कैसे संभाला जाना चाहिए? यह String.format के कारण है, लेकिन मुझे यकीन नहीं है कि इसे कैसे तय किया जाना चाहिए।
एंड्रॉयड डेवलपर

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

मुझे यह पसंद है क्योंकि इसका पालन करना आसान है और समझना आसान है।
जोशुआ पिंटर

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

अब एक पुस्तकालय उपलब्ध है जिसमें इकाई प्रारूपण शामिल है। मैंने इसे ट्रायवा लाइब्रेरी में जोड़ा , क्योंकि एंड्रॉइड के लिए केवल अन्य मौजूदा लाइब्रेरी एक है।

यह 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

ऑफ-चांस में यह किसी को थोड़ा समय बचाता है, या शायद थोड़े से मज़े के लिए, यहाँ एक गो संस्करण है। सरलता के लिए, मैंने केवल बाइनरी आउटपुट केस को शामिल किया है।

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 ("उचित प्रारूप में फ़ाइल का आकार:" + बाइट्स + "" + fileSizexnits [सूचकांक]); sizeToReturn = String.valueOf (बाइट्स) + "" + fileSizeUnits [सूचकांक]; वापसी का आकार }


1

ऊपर दिए गए जावा सही सर्वसम्मति उत्तर के लिए यहां 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 इकाइयों से चिपके रहते हैं, तो यह दिनचर्या संख्याओं के किसी भी नियमित उपयोग के लिए काम करती है। विशेषज्ञों से कई अन्य अच्छे जवाब हैं। मान लीजिए कि आप ग्रिड-इंटरव्यू पर संख्याओं का डेटाबाइंडिंग कर रहे हैं, तो इसके लायक प्रदर्शन की जांच करना उनके लिए अनुकूल दिनचर्या है।

PS: पोस्ट किया गया क्योंकि यह प्रश्न / उत्तर Google खोज पर शीर्ष पर आया था जबकि मैं C # प्रोजेक्ट कर रहा हूं।


1

आप StringUtils का उपयोग कर सकते हैं TraditionalBinarPrefix:

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

1

थोड़ा पुराना लेकिन, ... org.springframework.util.unit.DataSize कम से कम गणना के लिए इस पुनर्खरीद के लिए सूट कर सकता है, तो एक साधारण सज्जाकार करेगा


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

यह जवाब है, जबकि यह काम करता है, @ user601806 द्वारा इस सूत्र में पिछले एक जवाब देने के लिए एक पूरक है: stackoverflow.com/a/4888400/3987745 काम करने के लिए इस उत्तर के लिए, आप की जरूरत है अपाचे कॉमन्स आईओ ( commons.apache.org/proper/ commons-io ) निर्भरता।
एडवर्ड क्विक्सोट

0

क्या आपने जेएसआर 363 की कोशिश की है ? इसकी यूनिट विस्तार मॉड्यूल जैसे यूनिकोड सीएलडीआर ( गिटहब में : यूओएम-सिस्टम ) आपके लिए वह सब करते हैं।

आप MetricPrefixप्रत्येक कार्यान्वयन में शामिल कर सकते हैं या BinaryPrefix(ऊपर दिए गए कुछ उदाहरणों की तुलना में) और यदि आप उदाहरण के लिए भारत में या पास के देश में रहते हैं और काम करते हैं, IndianPrefix(यूओएम-सिस्टम के सामान्य मॉड्यूल में भी) आपको उपयोग करने और प्रारूप करने की अनुमति देता है "करोड़ बाइट्स "या" लाख बाइट्स "भी।


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 से कोटलिन में परिवर्तित किया गया है

/**
 * 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)
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.