java - बाइट आकार को जावा में मानव पठनीय प्रारूप में कैसे परिवर्तित करें?




formatting apache-commons (12)

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

यह 3 अलग-अलग प्रणालियों (एसआई, आईईसी, जेईडीईसी) और विभिन्न आउटपुट विकल्पों में मनमाने ढंग से सटीकता के साथ संख्याओं को प्रारूपित कर सकता है। त्रिवा इकाई परीक्षण से कुछ कोड उदाहरण यहां दिए गए हैं:

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

प्रिंटिंग सटीक किलो, मेगा मूल्य (यहां डब्ल्यू = वाट के साथ):

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

आउटपुट को कस्टमाइज़ करने के लिए आप एक दशमलव फोर्मेट पास कर सकते हैं:

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

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

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


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

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

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

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


मुझे पता है कि इस पोस्ट को अपडेट करने में बहुत देर हो चुकी है! लेकिन मुझे इसके साथ कुछ मज़ा आया:

एक इंटरफेस बनाएं:

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

यदि आप एंड्रॉइड का उपयोग करते हैं, तो आप बस 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;
    }

यह एयोब के जवाब का एक संशोधित संस्करण है।

परिवर्तन:

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

हम इकाइयों (जैसे बी, केबी, एमबी इत्यादि) के बीच कारक 1024 है जो 2 ^ 10 है, इसलिए सादगी बलिदान के बिना धीमी Math.pow() और Math.log() विधियों का उपयोग करने से पूरी तरह से बच सकते हैं। Long क्लास में एक आसान संख्या है numberOfLeadingZeros() विधि जिसका उपयोग हम यह कहने के लिए कर सकते हैं कि आकार का मूल्य किस इकाई में आता है।

मुख्य बिंदु: आकार इकाइयों की दूरी 10 बिट्स (1024 = 2 ^ 10) है जिसका अर्थ उच्चतम 1 बिट की स्थिति है - या दूसरे शब्दों में अग्रणी शून्यों की संख्या - 10 से भिन्न है (बाइट्स = केबी * 1024, केबी = एमबी * 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));
}

बाइट इकाइयों आपको ऐसा करने की अनुमति देता है:

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

एंड्रॉइड बिल्टिन क्लास का प्रयोग करें

एंड्रॉइड के लिए एक क्लास Formatter । बस कोड की तरह एक और आप कर रहे हैं।

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

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

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

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



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

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

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 (बाइट्स) + "" + fileSizeUnits [अनुक्रमणिका]; वापसी का आकार ToReturn; }






apache-commons