2010-07-16 15 views
102

Necesito mostrar un tamaño de archivo como Cadena mediante unidades sensibles.Formato de tamaño de archivo como MB, GB, etc.

p. Ej.

1L ==> "1 B"; 
1024L ==> "1 KB"; 
2537253L ==> "2.3 MB" 

etc.

He encontrado this previous answer, que yo no encontrar satisfactoria

he llegado con mi propia solución que tiene deficiencias similares:

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 String.format("%.1f %s", Double.valueOf(result), unit); 
} 

La principal El problema es mi conocimiento limitado de Decimalformat y/o String.format. Me gustaría 1024L, 1025L etc. para mapear a 1 KB en lugar de 1.0 KB.

Por lo tanto, dos posibilidades:

  1. yo preferiría una buena solución out-of-the-box en una biblioteca pública como bienes comunes Apache o Google guayaba.
  2. Si no la hay, puede que alguien me muestre cómo deshacerse de la parte' 0.0' (sin recurrir a la sustitución de cadenas y expresiones regulares, puedo hacerlo yo mismo)
+6

Ver esta respuesta: http://stackoverflow.com/a/3758880/34088 –

+0

Lo sé. Hubiera aceptado esa, si hubiera sido publicada aquí. –

+0

Si cambia la última línea para devolver NumberFormat.getFormat ("#, ## 0. #"). Format (result) + "" + unit; ¡también funciona en GWT! Gracias por esto, todavía no está en Guava. – tom

Respuesta

322
public static String readableFileSize(long size) { 
    if(size <= 0) return "0"; 
    final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" }; 
    int digitGroups = (int) (Math.log10(size)/Math.log10(1024)); 
    return new DecimalFormat("#,##0.#").format(size/Math.pow(1024, digitGroups)) + " " + units[digitGroups]; 
} 

Esto funcionará hasta 1000 TB .... y el programa es corto!

+0

Esta debería ser la respuesta "correcta" ya que toma en cuenta la unidad. –

+3

De acuerdo, debería ser la respuesta correcta. Mira [aquí] (http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java/3758880#3758880) para una salida aún mejor. – Kariem

+4

final String [] units = new String [] {"B", "KB", "MB", "GB", "TB", "EB"}; // ahora funciona hasta Long.MAX_VALUE! – Joe

7

Probablemente tendrá más suerte con java.text.DecimalFormat. Este código, probablemente debería hacerlo (solo improvisando, aunque ...)

new DecimalFormat("#,##0.#").format(value) + " " + unit

+0

perfecto, gracias! –

2

Sorprendentemente para mí, pero el algoritmo basado en bucle es aproximadamente un 10% más rápido.

public static String toNumInUnits(long bytes) { 
    int u = 0; 
    for (;bytes > 1024*1024; bytes >>= 10) { 
     u++; 
    } 
    if (bytes > 1024) 
     u++; 
    return String.format("%.1f %cB", bytes/1024f, " kMGTPE".charAt(u)); 
} 
+1

Todo está basado en bucle en la parte inferior. –

Cuestiones relacionadas