293 votos

¿Cómo convertir tamaño de bytes en formato legible humano en java?

¿Cómo convertir el tamaño de bytes en formato legible en Java? Como 1024 debe convertirse en "1 Kb" y 1024 * 1024 debe convertirse en "1 Mb".

Estoy harto de este método de utilidad para cada proyecto de escritura. ¿Hay algún métodos estáticos en Apache Commons para esto?

780voto

aioobe Puntos 158466

Aquí está mi ve en ello (sin bucles y maneja las unidades binarias y unidades):

public static String humanReadableByteCount(long bytes, boolean si) {
    int unit = si ? 1000 : 1024;
    if (bytes < unit) return bytes + " B";
    int exp = (int) (Math.log(bytes) / Math.log(unit));
    String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i");
    return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}

Ejemplo de la salida:

                              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)

154voto

user601806 Puntos 1039

FileUtils.byteCountToDisplaySize(long size)funcionaría si puede depender de su proyecto org.apache.commons.io .

JavaDoc para este método

16voto

Sean Patrick Floyd Puntos 109428

Me hizo la misma Pregunta hace poco:

Tamaño del formato de archivo como MB, GB, etc.

Mientras que no hay fuera-de-la-cuadro de respuesta, puedo vivir con la solución de:

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

Código de ensayo:

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

De salida (en mi configuración Regional alemana):

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

Edit: he abierto un Tema solicitando esta funcionalidad para Google Guayaba. Quizás alguien de cuidado de apoyo.

12voto

icza Puntos 3857

Podemos evitar completamente el uso de la lentitud Math.pow() y Math.log() métodos sin sacrificar la simplicidad ya que el factor entre las unidades (por ej. B, KB, MB, etc.) es de 1024, que es 2^10. La Long clase tiene un handy numberOfLeadingZeros() método que se puede utilizar para saber en que unidad el valor de tamaño de las caídas.

Punto clave: el Tamaño de las unidades tiene una distancia de 10 bits (1024=2^10) el sentido de la posición de las más altas de 1 bit o en otras palabras, el número de ceros a la izquierda - se diferencian por 10 (Bytes=KB*1024, KB=MB*resolución de 1024 etc.).

Correlación entre el número de ceros a la izquierda y el tamaño de la unidad:

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

El código final:

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

4voto

Lars Bohl Puntos 349

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

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: