web-dev-qa-db-fra.com

Conversion de Ko en Mo, Go, TB dynamiquement

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

Cette méthode doit renvoyer la taille en Go, Mo, Ko ou To. La valeur d'entrée est en Ko . Par exemple, le résultat pour 1245 devrait ressembler à 1,21 Mo mais je reçois 1,00 Mo.

12
pedja

Vous exécutez integer division. Donc, le résultat de la division est aussi integer. Et la partie décimale est tronquée.

so, 1245 / 1024 = 1

Changez votre division en floating point division: -

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

En outre, votre comparaison est défectueuse. Vous devriez faire la comparaison avec 1

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

Idéalement, je changerais votre comparaison en: -

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

Vous devez d'abord comparer l'unité supérieure, puis passer à l'unité inférieure.

25
Rohit Jain

Une version modifiée Appelle seulement le format une fois. Inclut "octets".

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

J'aime cela:

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

Le problème est que vous utilisez la division entière. Changez votre code pour:

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

Dans votre code d'origine, double m = size/1024 diviserait l'entier size par 1024, tronquerait le résultat en un entier et ne le convertirait ensuite qu'en double. C'est pourquoi la partie décimale s'est perdue.

5
NPE

Ce n'est pas facile à comprendre. Rohit Jain a mentionné l'opération de nombre entier. Arrondir peut également être un problème, car arrondir toujours vers le bas peut ne pas être souhaitable. Je conseillerais d’opter pour une solution disponible comme dans la bibliothèque triava .

Il peut formater des nombres avec une précision arbitraire, dans 3 systèmes différents (SI, CEI, JEDEC) et diverses options de sortie. Voici quelques exemples de code issus des tests unitaires triava :

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

Impression du kilo exact, des valeurs méga (ici avec W = Watt):

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

Vous pouvez passer un DecimalFormat pour personnaliser la sortie:

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

Pour des opérations arbitraires sur des valeurs en kilo ou méga, vous pouvez les scinder en composants:

UnitComponent uc = new  UnitComponent(123_345_567_789L, UnitSystem.SI);
int kilos = uc.kilo(); // 567
int gigas = uc.giga(); // 123
3
Christian Esken

Vous effectuez une division entière, 

c'est-à-dire que 31/15 donnera 2, pas 2. quoi que

il suffit d’ajouter le numéro avec D ou d qui le désigne comme un double et tout ira bien 

double m = size/1024D;
double g = size/1048576D;
double t = size/1073741824D;
3
PermGenError
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;
}

Ajoutez simplement plus d'unités de fichier (s'il en manque) et vous verrez la taille de l'unité jusqu'à cette unité (si votre fichier a une longueur aussi importante)

2
Vishwajit R. Shinde

La réponse de bickster fonctionne assez bien, mais le problème est qu’elle renvoie des résultats tels que 45.00 Bytes et 12.00 KB. À mon avis, les derniers chiffres décimaux devraient être supprimés s’il s’agit de zéros. Ainsi, au lieu de 45.00 Bytes et 12.00 KB, vous obtenez 45 B et 12 KB (remarquez que Bytes a été remplacé par B. Ceci est juste pour l’uniformité puisque nous avons KB, MB, etc., et non kilo-octets, mégaoctets, 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;
        }
    }

La méthode ci-dessus vérifie simplement si la valeur comporte des zéros sous forme de chiffres décimaux.

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

Ma version de base (vous POUVEZ définir des constantes au lieu de calculer POW tout le temps):

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?)";
}
0
Buffalo
class ConverterUtils{
    public static void main(String[] args) {
        System.out.println(getSize(1234567));
    }
    public static String getSize(long size) {
        String s = "";
        double kb = size / 1024;
        double mb = kb / 1024;
        double gb = kb / 1024;
        double tb = kb / 1024;
        if(size < 1024) {
            s = size + " Bytes";
        } else if(size >= 1024 && size < (1024 * 1024)) {
            s =  String.format("%.2f", kb) + " KB";
        } else if(size >= (1024 * 1024) && size < (1024 * 1024 * 1024)) {
            s = String.format("%.2f", mb) + " MB";
        } else if(size >= (1024 * 1024 * 1024) && size < (1024 * 1024 * 1024 * 1024)) {
            s = String.format("%.2f", gb) + " GB";
        } else if(size >= (1024 * 1024 * 1024 * 1024)) {
            s = String.format("%.2f", tb) + " TB";
        }
        return s;
    }
}

Pour mieux comprendre - https://www.techspot.com/news/68482-quickly-convert-between-storage-sorage-units-kb-mb.html

0
Ilya Budu