691 Stimmen

Wie kann ich in Java die Bytegröße in ein für Menschen lesbares Format umwandeln?

Wie kann ich in Java die Bytegröße in ein für Menschen lesbares Format umwandeln?

So sollte 1024 zu "1 Kb" und 1024*1024 zu "1 Mb" werden.

Ich bin es leid, diese Dienstprogrammmethode für jedes Projekt zu schreiben. Gibt es eine statische Methode in Apache Commons für das hier?

43 Stimmen

Wenn Sie die standardisierten Einheiten verwenden, sollte 1024 zu "1KiB" und 1024*1024 zu "1MiB" werden. de.wikipedia.org/wiki/Binary_prefix

0 Stimmen

@Pascal: Es sollte mehrere Funktionen oder eine Option zur Angabe der Basis und der Einheit geben.

0 Stimmen

1501voto

aioobe Punkte 397211

Lustige Tatsache: Das ursprüngliche Snippet, das hier gepostet wurde, war das meistkopierte Java-Snippet aller Zeiten auf Stack Overflow, und es war fehlerhaft. Er wurde zwar korrigiert, aber es wurde unübersichtlich.

Die ganze Geschichte in diesem Artikel: Der meistkopierte Stack Overflow-Snippet aller Zeiten ist fehlerhaft!

Quelle: Formatierung der Bytegröße in ein für Menschen lesbares Format | 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());
}

Binär (1 Ki = 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());
}

Beispielhafte Ausgabe:

                             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)

384voto

user601806 Punkte 3647

FileUtils.byteCountToDisplaySize(long size) würde funktionieren, wenn Ihr Projekt abhängig ist von org.apache.commons.io .

JavaDoc für diese Methode

218voto

AZ_ Punkte 36741

Eine in Android integrierte Klasse verwenden

Für Android gibt es eine Klasse, Formatierer . Nur eine Zeile Code und Sie sind fertig.

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

Es ist wie formatFileSize() , sondern versuchen, kürzere Zahlen (mit weniger Dezimalstellen) zu erzeugen.

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

Sie formatiert die Größe eines Inhalts in Form von Bytes, Kilobytes, Megabytes usw.

93voto

icza Punkte 335148

Wir können die Verwendung der langsamen Math.pow() y Math.log() Methoden, ohne auf Einfachheit zu verzichten, da der Faktor zwischen den Einheiten (z. B. B, KB, MB usw.) 1024 beträgt, was 2^10 entspricht. Die Long Klasse hat eine praktische numberOfLeadingZeros() Methode, mit der wir feststellen können, in welche Einheit der Größenwert fällt.

Wichtigster Punkt: Größeneinheiten haben einen Abstand von 10 Bits (1024 = 2^10), was bedeutet, dass die Position des höchsten Bits - oder mit anderen Worten die Anzahl der führenden Nullen -Differenz durch 10 (Bytes = KB*1024, KB = MB*1024, usw.).

Korrelation zwischen der Anzahl der führenden Nullen und der Größeneinheit:

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

Der endgültige Code:

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

29voto

Sean Patrick Floyd Punkte 283617

Die gleiche Frage habe ich mir kürzlich gestellt:

Formatieren Sie die Dateigröße als MB, GB, usw.

Es gibt zwar keine Patentlösung, aber ich kann mit dieser Lösung leben:

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

Test-Code:

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

Ausgabe (in meinem deutschen Gebietsschema):

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

Ich habe ein Problem bei der Anforderung dieser Funktionalität für Google Guava . Vielleicht hat jemand Lust, sie zu unterstützen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X