web-dev-qa-db-fra.com

Comment puis-je obtenir la taille d'un dossier sur la carte SD sous Android?

Est-il possible d’obtenir facilement la taille d’un dossier sur la carte SD? J'utilise un dossier pour la mise en cache des images et j'aimerais présenter la taille totale de toutes les images en cache. Existe-t-il un autre moyen de procéder à une itération sur chaque fichier? Ils résident tous dans le même dossier?

26
Gunnar Lium

Il suffit de parcourir tous les fichiers et d’en résumer la longueur:

/**
 * Return the size of a directory in bytes
 */
private static long dirSize(File dir) {

    if (dir.exists()) {
        long result = 0;
        File[] fileList = dir.listFiles();
        for(int i = 0; i < fileList.length; i++) {
            // Recursive call if it's a directory
            if(fileList[i].isDirectory()) {
                result += dirSize(fileList [i]);
            } else {
                // Sum the file size in bytes
                result += fileList[i].length();
            }
        }
        return result; // return the file size
    }
    return 0;
}

NOTE: Fonction écrite à la main pour ne pas pouvoir compiler!

EDITED: appel récursif fixé.

EDITED: dirList.length a été remplacé par fileList.length.

38
Moss

Voici un code qui évite la récursivité et calcule également la taille physique au lieu de la taille logique:

public static long getFileSize(final File file) {
    if (file == null || !file.exists())
        return 0;
    if (!file.isDirectory())
        return file.length();
    final List<File> dirs = new LinkedList<>();
    dirs.add(file);
    long result = 0;
    while (!dirs.isEmpty()) {
        final File dir = dirs.remove(0);
        if (!dir.exists())
            continue;
        final File[] listFiles = dir.listFiles();
        if (listFiles == null || listFiles.length == 0)
            continue;
        for (final File child : listFiles) {
            result += child.length();
            if (child.isDirectory())
                dirs.add(child);
        }
    }
    return result;
}
14

vous devriez utiliser ce code:

public static long getFolderSize(File f) {
    long size = 0;
    if (f.isDirectory()) {
        for (File file : f.listFiles()) {    
            size += getFolderSize(file);
        }
    } else {
        size=f.length();
    }
    return size;
}
5
Linh Toòng
/**
 * Try this one for better performance
 * Mehran
 * Return the size of a directory in bytes
 **/

private static long dirSize(File dir) {
    long result = 0;

    Stack<File> dirlist= new Stack<File>();
    dirlist.clear();

    dirlist.Push(dir);

    while(!dirlist.isEmpty())
    {
        File dirCurrent = dirlist.pop();

        File[] fileList = dirCurrent.listFiles();
        for(File f: fileList){
            if(f.isDirectory())
                dirlist.Push(f);
            else
                result += f.length();
        }
    }

    return result;
}
5
Mehran

La voie de #Moss est la bonne. Ceci est mon code pour ceux qui veulent changer les octets en un format lisible par l'homme. Vous avez juste besoin d’affecter le chemin de votre dossier à dirSize(String path) et d’obtenir un format lisible par l’homme basé sur les octets, les kilos, les méga, etc. 

private static String dirSize(String path) {

        File dir = new File(path);

        if(dir.exists()) {
            long bytes = getFolderSize(dir);
            if (bytes < 1024) return bytes + " B";
            int exp = (int) (Math.log(bytes) / Math.log(1024));
            String pre = ("KMGTPE").charAt(exp-1) + "";

            return String.format("%.1f %sB", bytes / Math.pow(1024, exp), pre);
        }

        return "0";
    }

    public static long getFolderSize(File dir) {
        if (dir.exists()) {
            long result = 0;
            File[] fileList = dir.listFiles();
            for(int i = 0; i < fileList.length; i++) {
                // Recursive call if it's a directory
                if(fileList[i].isDirectory()) {
                    result += getFolderSize(fileList[i]);
                } else {
                    // Sum the file size in bytes
                    result += fileList[i].length();
                }
            }
            return result; // return the file size
        }
        return 0;
    } 
3
Hesam

Le problème avec les autres solutions est qu’elles ne vous fournissent que la taille logique de tous les fichiers du répertoire spécifié. Ce sera différent de l'espace réellement utilisé (physique). Si votre répertoire contient de nombreux sous-répertoires et/ou petits fichiers, il peut y avoir une différence énorme entre la taille logique et réelle du répertoire.

Voici ce que j'ai trouvé comment prendre en compte la structure physique de la FS.

public static long getDirectorySize(File directory, long blockSize) {
    File[] files = directory.listFiles();
    if (files != null) {

        // space used by directory itself 
        long size = file.length();

        for (File file : files) {
            if (file.isDirectory()) {
                // space used by subdirectory
                size += getDirectorySize(file, blockSize);
            } else {
                // file size need to rounded up to full block sizes
                // (not a perfect function, it adds additional block to 0 sized files
                // and file who perfectly fill their blocks) 
                size += (file.length() / blockSize + 1) * blockSize;
            }
        }
        return size;
    } else {
        return 0;
    }
}

Vous pouvez utiliser StatFs pour obtenir la taille du bloc:

public static long getDirectorySize(File directory) {
    StatFs statFs = new StatFs(directory.getAbsolutePath());
    long blockSize;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        blockSize = statFs.getBlockSizeLong()
    } else {
        blockSize = statFs.getBlockSize();
    }

    return getDirectorySize(directory, blockSize);
}
3
Aleksejs Mjaliks

méthode ci-dessous retourne la taille du dossier: -

public static long getFolderSize(File dir) {
long size = 0;
for (File file : dir.listFiles()) {
    if (file.isFile()) {
        // System.out.println(file.getName() + " " + file.length());
        size += file.length();
    } else
        size += getFolderSize(file);
}
return size;
}

appelez la méthode ci-dessus: -

File file = new File(Environment.getExternalStorageDirectory().getPath()+"/urfoldername/");

long folder_size=getFolderSize(file);

vous retourne la taille du dossier.

1
duggu

Vous pouvez interroger MediaStore pour une taille de répertoire sur la mémoire interne. C'est beaucoup plus rapide qu'une méthode récursive qui obtient la longueur de chaque fichier dans un répertoire. Vous devez avoir l'autorisation READ_EXTERNAL_STORAGE accordée.

Exemple:

/**
 * Query the media store for a directory size
 *
 * @param context
 *     the application context
 * @param file
 *     the directory on primary storage
 * @return the size of the directory
 */
public static long getFolderSize(Context context, File file) {
  File directory = readlink(file); // resolve symlinks to internal storage
  String path = directory.getAbsolutePath();
  Cursor cursor = null;
  long size = 0;
  try {
    cursor = context.getContentResolver().query(MediaStore.Files.getContentUri("external"),
        new String[]{MediaStore.MediaColumns.SIZE},
        MediaStore.MediaColumns.DATA + " LIKE ?",
        new String[]{path + "/%/%"},
        null);
    if (cursor != null && cursor.moveToFirst()) {
      do {
        size += cursor.getLong(0);
      } while (cursor.moveToNext());
    }
  } finally {
    if (cursor != null) {
      cursor.close();
    }
  }
  return size;
}

/**
 * Canonicalize by following all symlinks. Same as "readlink -f file".
 *
 * @param file
 *     a {@link File}
 * @return The absolute canonical file
 */
public static File readlink(File file) {
  File f;
  try {
    f = file.getCanonicalFile();
  } catch (IOException e) {
    return file;
  }
  if (f.getAbsolutePath().equals(file.getAbsolutePath())) {
    return f;
  }
  return readlink(f);
}

Utilisation:

File DCIM = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
long directorySize = getFolderSize(context, DCIM);
String formattedSize = Formatter.formatFileSize(context, directorySize);
System.out.println(DCIM + " " + formattedSize);

Sortie:

/ stockage/émulé/0/DCIM 30.86 MB

0
Jared Rummler

J'espère que cela t'aides

importer cette

import Android.text.format.Formatter;

Pour la taille du fichier

public static String fileSize(File file, Context context) {
        return Formatter.formatFileSize(context, file.length());
    }

Pour la taille du dossier

 public static String forlderSize(File file, Context context) {
        long length = 0;
        File[] folderFiles = file.listFiles();
        for (File f : folderFiles) {
            length += f.length();
        }

        return Formatter.formatFileSize(context, length);
    }
0
zaai

Une itération dans tous les fichiers nécessite moins de 5 lignes de code et constitue le seul moyen raisonnable de procéder. Si vous voulez devenir laid, vous pouvez également exécuter une commande système (Runtime.getRuntime (). Exec ("du");) et intercepter la sortie;)

0
Maurits Rijk