2010-07-16 18 views
102

Ho bisogno di visualizzare una dimensione del file come String usando unità sensibili.Formato del file come MB, GB ecc.

ad es.

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

ecc

ho trovato this previous answer, che non ho trovato soddisfacente

Sono venuto con la mia soluzione che ha carenze simili:

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

Il principale il problema è la mia conoscenza limitata di Decimalformat e/o String.format. Desidero 1024L, 1025L ecc. Per mappare a 1 KB anziché a 1.0 KB.

Così, due possibilità:

  1. io preferirei una buona soluzione out-of-the-box in una biblioteca pubblica come bene comune Apache o google guava.
  2. Se non c'è, qualcuno mi può mostrare come sbarazzarsi della parte' 0,0' (senza ricorrere alla sostituzione di stringa e regex, posso farlo io stesso)
+6

Vedere questa risposta: http://stackoverflow.com/a/3758880/34088 –

+0

Lo so. L'avrei accettato, se fosse stato pubblicato qui. –

+0

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

risposta

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

Ciò funzionerà fino a 1000 TB .... e il programma è breve!

+0

Questa dovrebbe essere la risposta "corretta" in quanto tiene conto dell'unità. –

+3

Accetto, dovrebbe essere la risposta corretta. Guarda [qui] (http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java/3758880#3758880) per un risultato ancora migliore. – Kariem

+4

final String [] units = new String [] {"B", "KB", "MB", "GB", "TB", "EB"}; // ora funziona fino a Long.MAX_VALUE! – Joe

7

Probabilmente dovrete più fortuna con java.text.DecimalFormat. Questo codice dovrebbe probabilmente farlo (solo alate però ...)

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

+0

perfetto, grazie! –

2

Sorprendentemente per me, ma l'algoritmo basato su loop è circa il 10% più veloce.

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

Tutto è basato sul loop in basso. –

Problemi correlati