Come convertire le dimensioni dei byte in formato leggibile dall'uomo in Java?


556

Come convertire le dimensioni dei byte in formato leggibile dall'uomo in Java? Come 1024 dovrebbe diventare "1 Kb" e 1024 * 1024 dovrebbe diventare "1 Mb".

Sono stufo di scrivere questo metodo di utilità per ogni progetto. Ci sono metodi statici in Apache Commons per questo?


32
Se si utilizzano le unità standardizzate, 1024 dovrebbe diventare "1 KiB" e 1024 * 1024 dovrebbe diventare "1 MiB". en.wikipedia.org/wiki/Binary_prefix
Pascal Cuoq

@Pascal: ci dovrebbero essere diverse funzioni o un'opzione per specificare la base e l'unità.
Aaron Digulla,


3
@Pascal Cuoq: grazie per il riferimento. Non mi sono reso conto fino a quando non l'ho letto che qui nell'UE ci viene richiesto di utilizzare i prefissi corretti per legge.
JeremyP,

2
@DerMike Hai detto che "Fino a quando non esiste una libreria del genere". Questo ora è diventato vero. :-) stackoverflow.com/questions/3758606/...
Christian Esken

Risposte:


1310

Curiosità: lo snippet originale pubblicato qui era lo snippet Java più copiato di tutti i tempi su Stack Overflow ed era difettoso. È stato risolto ma è diventato disordinato.

Articolo completo in questo articolo: lo snippet StackOverflow più copiato di tutti i tempi è imperfetto!

Fonte: formattazione della dimensione dei byte in formato leggibile | 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());
}

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

Esempio di output:

                              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
Preferisco 1.0 KB. Quindi è chiaro quante cifre significative comporta l'output. (Questo sembra essere anche il comportamento di, ad esempio, il ducomando in Linux.)
aioobe,

19
Penso che tutti dovrebbero notare che nel tuo progetto il cliente vuole vedere i valori in base 2 (diviso per 1024) ma con prefisso comune. Non KiB, MiB, GiB ecc. Usa KB, MB, GB, TB per questo.
Borys,

27
@Borys L'uso di "KB" per indicare "1024 byte" è errato. Non farlo.
endolith il

8
I lettori lo impareranno. Meglio qualcosa con cui non hanno familiarità e che possono imparare che avere qualcosa di sbagliato. Scrivere in KB un utente che ne ha familiarità si aspetta 1000 e un utente che non ha familiarità si aspetta 1024.
Kap

16
Risposta riscritta interamente. Molti dei commenti sopra sono obsoleti.
aioobe,

305

FileUtils.byteCountToDisplaySize(long size)funzionerebbe se il tuo progetto può dipendere org.apache.commons.io.

JavaDoc per questo metodo


18
Ho già commons-io nel mio progetto, ma ho finito per usare il codice di aioobe, a causa del comportamento di arrotondamento (vedi il link per JavaDoc)
Iravanchi,

3
c'è un'utilità per fare l'operazione inversa. Ottenere il conteggio dei byte dal conteggio dei byte leggibili dall'uomo?
arunmoezhi,

6
Sfortunatamente questa funzione non è compatibile con le impostazioni locali; in francese, ad esempio, chiamano sempre byte "ottetti", quindi se hai intenzione di mostrare un file da 100 KB a un utente francese, l'etichetta corretta sarebbe 100 Ko.
Tacroy,

@Tacroy È possibile ottenere l'output di ottetti con UnitFormatter nella libreria triava. Puoi passare qualsiasi unità per byte, Watt o ottetti. Esempio, leggermente modificato dagli esempi in github.com/trivago/triava : UnitFormatter.formatAsUnit (1126, UnitSystem.SI, "o"); // = "1.13 ko" Altri esempi in: stackoverflow.com/questions/3758606/...
Christian Esken

5
questo arrotonda al GB più vicino quando> 1 GB, il che significa che la precisione che ne ottieni varia
tksfz

180

Usa la classe integrata di Android

Per Android esiste un programma di formattazione . Basta una riga di codice e il gioco è fatto.

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

È come formatFileSize(), ma cercando di generare numeri più brevi (mostrando meno decimali).

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

Formatta una dimensione del contenuto in forma di byte, kilobyte, megabyte, ecc.


12
dovrebbe essere la migliore risposta definitiva per ANDROID. Non sono necessarie librerie extra. +1
Dieter,

11
Odio il fatto che tu debba passare Context.
Jared Burrows,

4
Dovrebbe essere la risposta migliore per ANDROID in modo definitivo.
Shridutt Kothari,

5
Si passa al contesto, quindi viene tradotto nelle impostazioni internazionali correnti dell'utente. Altrimenti non sarebbe una funzione molto utile.
phreakhead,

7
Stavo usando la risposta accettata prima di sapere questo. Per essere notato, in Build.VERSION_CODES.N e versioni precedenti, vengono utilizzati invece i poteri di 1024, con KB = 1024 byte, MB = 1.048.576 byte, ecc. A partire da O, i prefissi vengono utilizzati nei loro significati standard nel sistema SI , quindi kB = 1000 byte, MB = 1.000.000 di byte, ecc.
HendraWD,

57

Possiamo evitare completamente di usare i metodi lenti Math.pow()e Math.log()senza sacrificare la semplicità poiché il fattore tra le unità (ad es. B, KB, MB ecc.) È 1024 che è 2 ^ 10. La Longclasse ha un numberOfLeadingZeros()metodo utile che possiamo usare per dire in quale unità rientra il valore della dimensione.

Punto chiave: le unità di dimensione hanno una distanza di 10 bit (1024 = 2 ^ 10), il che significa che la posizione del 1 bit più alto, ovvero il numero di zeri iniziali , differisce di 10 (byte = KB * 1024, KB = MB * 1024 ecc.).

Correlazione tra numero di zeri iniziali e unità di misura:

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

Il codice finale:

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

Ho fatto la stessa domanda di recente:

Formatta le dimensioni del file come MB, GB ecc

Mentre non esiste una risposta pronta all'uso, posso convivere con la soluzione:

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

Codice di prova:

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

Output (sulla mia lingua tedesca):

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

Modifica: ho aperto un numero che richiede questa funzionalità per Google Guava . Forse qualcuno vorrebbe supportarlo.


2
Perché 0 ha una dimensione file non valida?
aioobe,

@aioobe era nel mio caso d'uso (mostra la dimensione di un file caricato), ma probabilmente non è universale
Sean Patrick Floyd,

Se si modifica l'ultima riga per restituire NumberFormat.getFormat ("#, ## 0. #"). Format (risultato) + "" + unità; funziona anche in GWT! Grazie per questo, non è ancora in Guava.
tom

9

Questa è una versione modificata della risposta di aioobe .

I cambiamenti:

  • Localeparametro, perché alcune lingue usano .e altre ,come punto decimale.
  • codice leggibile dall'uomo

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

È un risultato un po 'misto per passare un parametro Locale solo per i simboli del separatore, ma poi non localizzare l'unità per tenere conto delle lingue che usano anche un simbolo diverso per i byte, come il francese.
Nzall,

@Nzall Intendi l'ottetto? Wikipedia afferma che non è più comune. Altrimenti, hai un riferimento?
Christian Strempfer,

7

Se usi Android, puoi semplicemente usare android.text.format.Formatter.formatFileSize () .

In alternativa, ecco una soluzione basata su questo post popolare :

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

O a Kotlin:

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

Sembra che tu abbia un errore off-by-one nel tuo for-loop. Penso che dovrebbe essere unitsCounte non unitsCount-1.
aioobe,

@aioobe ma questo significa che il ciclo può interrompersi quando i == unitsCount, che significa i == 6, che significa che "charAt" fallirà ...
sviluppatore Android

if(result<unit) break;entrerà prima di quello. Nessun problema. (Se lo provi, noterai che puoi saltare completamente la condizione for-loop.)
aioobe

@aioobe Corretto, questo è dovuto al presupposto (che è corretto) che gestisco il tipo di variabile "lungo". Inoltre, si basa sul presupposto che le unità saranno almeno ciò che ho scritto. Se usi meno unità, produrrà risultati strani (preferirai valori inferiori a 1, piuttosto che maggiori di 1000).
sviluppatore Android

@aioobe Correct. Io lo aggiusterò. A proposito, il tuo algoritmo può anche fornire un risultato strano. prova a dargli "999999, vero" come argomento. mostrerà "1000.0 kB", quindi è arrotondato, ma quando le persone lo vedono, possono chiedersi: perché non può mostrare 1 MB, come 1000 KB = 1 MB ... Come pensi che debba essere gestito? È a causa di String.format, ma non sono sicuro di come debba essere risolto.
sviluppatore 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";
        }
    }

Mi piace perché è facile da seguire e da capire.
Joshua Pinter,

6

Byte Units ti permette di farlo in questo modo:

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

Ho scritto un'altra libreria chiamata unità di memoria che ti permette di farlo in questo modo:

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

Nel caso in cui si desideri forzare una determinata unità, procedere come segue:

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

Ora è disponibile una libreria che contiene la formattazione dell'unità. L'ho aggiunto alla triava libreria , poiché l'unica altra libreria esistente sembra essere una per Android.

Può formattare numeri con precisione arbitraria, in 3 diversi sistemi (SI, IEC, JEDEC) e varie opzioni di output. Ecco alcuni esempi di codice tratti dai test unitari di triava :

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

Stampa chilo esatto, valori mega (qui con W = Watt):

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

È possibile passare un formato decimale per personalizzare l'output:

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

Per operazioni arbitrarie su chilogrammi o mega valori, è possibile dividerli in componenti:

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

2

So che è troppo tardi per aggiornare questo post! ma mi sono divertito un po 'con questo:

Crea un'interfaccia:

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

Crea classe 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.#");
}
}

Chiamalo:

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

Produzione:

21.4kB
2GB

2

Nel caso in cui si risparmia un po 'di tempo, o forse solo per un po' di divertimento, ecco una versione Go. Per semplicità, ho incluso solo il caso di output binario.

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

Basta aggiungere più unità di file (se mancano) e vedrai le dimensioni dell'unità fino a quell'unità (se il tuo file ha quella lunghezza) System.out.println ("Dimensioni del file nel formato corretto:" + byte + "" + fileSizeUnits [indice]); sizeToReturn = String.valueOf (bytes) + "" + fileSizeUnits [indice]; restituire sizeToReturn; }


1

Ecco l'equivalente C # .net per la risposta di consenso corretta Java sopra. (ce n'è un altro sotto che ha codici più brevi)

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

Tecnicamente parlando, se ci atteniamo alle unità SI, questa routine funziona per qualsiasi uso regolare dei numeri. Ci sono molte altre buone risposte da parte di esperti. Supponiamo che tu stia eseguendo il databinding dei numeri sulle visualizzazioni della griglia, vale la pena verificare da loro le routine ottimizzate per le prestazioni.

PS: Inserito perché questa domanda / risposta è venuta in cima alla ricerca di Google mentre sto facendo il progetto C #.


1

È possibile utilizzare StringUtils s’ TraditionalBinarPrefix:

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

1

un po 'vecchio ma ... org.springframework.util.unit.DataSize potrebbe adattarsi a questa esigenza almeno per il calcolo, quindi un semplice decoratore farà


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

Questa risposta, mentre si lavora, è un complemento ad una precedente risposta in questa discussione da @ user601806: stackoverflow.com/a/4888400/3987745 Per questa risposta al lavoro, è necessario Apache Commons IO ( commons.apache.org/proper/ commons-io ) dipendenza.
Edward Chisciotte,

0

Hai provato JSR 363 ? I suoi moduli di estensione unità come Unicode CLDR (in GitHub: uom-systems ) fanno tutto questo per te.

Puoi usare MetricPrefixincluso in ogni implementazione o BinaryPrefix(paragonabile ad alcuni degli esempi sopra) e se ad esempio vivi e lavori in India o in un paese vicino IndianPrefix(anche nel modulo comune di uom-system) ti consente di utilizzare e formattare "Crore Byte "o" Lakh Bytes ".


0

Forse puoi usare questo codice (in 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

Utilizzare la seguente funzione per ottenere informazioni esatte, generata prendendo la base del ATM_CashWithdrawlconcetto.

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

Ho appena modificato il codice di facebookarchiveStringUtils per ottenere il formato seguente. Lo stesso formato che otterrai quando usi 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;
}

Esempio di utilizzo dei metodi precedenti:

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

Byte per ottenere sopra il formato

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

Per visualizzare l'ora in formato leggibile dall'uomo, utilizzare questa funzione millisToShortDHMS(long duration) .


0

ecco la conversione da @aioobe convertita in 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)
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.