Convertendo KB em MB, GB, TB dinamicamente

public String size(int size){ String hrSize = ""; int k = size; double m = size/1024; double g = size/1048576; double t = size/1073741824; DecimalFormat dec = new DecimalFormat("0.00"); if (k>0) { hrSize = dec.format(k).concat("KB"); } if (m>0) { hrSize = dec.format(m).concat("MB"); } if (g>0) { hrSize = dec.format(g).concat("GB"); } if (t>0) { hrSize = dec.format(t).concat("TB"); } return hrSize; } 

Este é um método que deve retornar o tamanho em GB, MB, KB ou TB. O valor de input está em KB. por exemplo, o resultado para 1245 deve ser como 1.21MB, mas o que obtenho é 1.00MB.

Você está executando uma integer division . Então o resultado da divisão é também integer . E parte fracionária é truncada.

 so, 1245 / 1024 = 1 

Mude sua divisão para divisão de floating point division : –

 double m = size/1024.0; double g = size/1048576.0; double t = size/1073741824.0; 

Além disso, sua comparação está com defeito. Você deve fazer a comparação com 1 .

 if (m > 1), if (t > 1), if (g > 1) 

Idealmente, eu mudaria sua comparação para:

  if (t > 1) { hrSize = dec.format(t).concat("TB"); } else if (g > 1) { hrSize = dec.format(g).concat("GB"); } else if (m > 1) { hrSize = dec.format(m).concat("MB"); } else { hrSize = dec.format(size).concat("KB"); } 

Você precisa comparar primeiro com a unidade mais alta e depois passar para a inferior.

Uma versão modificada Apenas chama o formato uma vez. Inclui “Bytes”.

 public static String formatFileSize(long size) { String hrSize = null; double b = size; double k = size/1024.0; double m = ((size/1024.0)/1024.0); double g = (((size/1024.0)/1024.0)/1024.0); double t = ((((size/1024.0)/1024.0)/1024.0)/1024.0); DecimalFormat dec = new DecimalFormat("0.00"); if ( t>1 ) { hrSize = dec.format(t).concat(" TB"); } else if ( g>1 ) { hrSize = dec.format(g).concat(" GB"); } else if ( m>1 ) { hrSize = dec.format(m).concat(" MB"); } else if ( k>1 ) { hrSize = dec.format(k).concat(" KB"); } else { hrSize = dec.format(b).concat(" Bytes"); } return hrSize; } 

Eu amo isto:

 public static String getDynamicSpace(long diskSpaceUsed) { if (diskSpaceUsed <= 0) { return "0"; } final String[] units = new String[] { "B", "KiB", "MiB", "GiB", "TiB" }; int digitGroups = (int) (Math.log10(diskSpaceUsed) / Math.log10(1024)); return new DecimalFormat("#,##0.#").format(diskSpaceUsed / Math.pow(1024, digitGroups)) + " " + units[digitGroups]; } 

O problema é que você está usando a divisão inteira. Altere seu código para:

 double m = size/1024.0; double g = size/1048576.0; double t = size/1073741824.0; 

Em seu código original, double m = size/1024 dividiria o size inteiro por 1024 , truncaria o resultado para um inteiro, e só então o converteria para o double . É por isso que a parte fracionária estava se perdendo.

Você está realizando uma divisão inteira,

ou seja, 31/15 resultará em 2, não 2.que seja

basta acrescentar o número com D ou d que denota como um duplo e você vai ficar bem

 double m = size/1024D; double g = size/1048576D; double t = size/1073741824D; 

Não é fácil acertar isso. Rohit Jain mencionou a operação inteira. O arredondamento também pode ser um problema, pois o arredondamento para baixo pode não ser desejável. Eu aconselharia a ir para uma solução disponível como na biblioteca triava .

Pode formatar números com precisão arbitrária, em 3 sistemas diferentes (SI, IEC, JEDEC) e várias opções de saída. Aqui estão alguns exemplos de código dos testes de unidade triava :

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

Imprimindo quilo exato, mega valores (aqui com W = Watt):

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

Você pode passar um DecimalFormat para personalizar a saída:

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

Para operações arbitrárias em kilo ou mega valores, você pode dividi-los em componentes:

 UnitComponent uc = new UnitComponent(123_345_567_789L, UnitSystem.SI); int kilos = uc.kilo(); // 567 int gigas = uc.giga(); // 123 
 String[] fileSizeUnits = {"bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}; public String calculateProperFileSize(double bytes){ String sizeToReturn = "";// = FileUtils.byteCountToDisplaySize(bytes), unit = ""; int index = 0; for(index = 0; index < fileSizeUnits.length; index++){ if(bytes < 1024){ break; } bytes = bytes / 1024; } System.out.println("Systematic file size: " + bytes + " " + fileSizeUnits[index]); sizeToReturn = String.valueOf(bytes) + " " + fileSizeUnits[index]; return sizeToReturn; } 

Basta adicionar mais unidades de arquivo (se houver alguma falta) e você verá o tamanho da unidade até essa unidade (se o arquivo tiver esse tamanho)

Minha versão básica (você pode definir algumas constantes em vez de calcular o POW o tempo todo):

 public static String GetFolderSizeHuman(long aBytes) { if (aBytes < 1024 * 1024) return aBytes + " KB"; else if (aBytes < Math.pow(2, 20) * 1024) return (int) aBytes / Math.pow(2, 20) + " MB"; else if (aBytes < Math.pow(2, 30) * 1024 ) return kGbTbFormatter.format(aBytes / Math.pow(2, 30)) + " GB"; else if (aBytes < Math.pow(2, 40) * 1024) return kGbTbFormatter.format(aBytes / Math.pow(2, 40)) + " TB"; else return "N/A (1TB?)"; } 

resposta do bickster funciona muito bem, mas o problema com isso é que ele retorna resultados como 45.00 Bytes e 12.00 KB . Na minha opinião, os últimos dígitos decimais devem ser removidos se forem zeros. Então, em vez de 45.00 Bytes e 12.00 KB , você obtém 45 B e 12 KB (observe que Bytes foi alterado para B Isso é apenas para uniformidade, pois temos KB, MB, etc. e não Kilobytes, Megabytes, etc.).

 private boolean isDouble(double value) { if (value % 1 == 0) { Log.d(TAG, "value is " + value + " and is not double"); return false; } else { Log.d(TAG, "value is " + value + " and is double"); return true; } } 

O método acima simplesmente verifica se o valor tem zeros como dígitos decimais.

 private String formatFileSize(long size) { String hrSize = null; double b = size; double k = size/1024.0; double m = ((size/1024.0)/1024.0); double g = (((size/1024.0)/1024.0)/1024.0); double t = ((((size/1024.0)/1024.0)/1024.0)/1024.0); DecimalFormat dec1 = new DecimalFormat("0.00"); DecimalFormat dec2 = new DecimalFormat("0"); if (t>1) { hrSize = isDouble(t) ? dec1.format(t).concat(" TB") : dec2.format(t).concat(" TB"); } else if (g>1) { hrSize = isDouble(g) ? dec1.format(g).concat(" GB") : dec2.format(g).concat(" GB"); } else if (m>1) { hrSize = isDouble(m) ? dec1.format(m).concat(" MB") : dec2.format(m).concat(" MB"); } else if (k>1) { hrSize = isDouble(k) ? dec1.format(k).concat(" KB") : dec2.format(k).concat(" KB"); } else { hrSize = isDouble(b) ? dec1.format(b).concat(" B") : dec2.format(b).concat(" B"); } return hrSize; } 
Intereting Posts