Obtenir la taille du fichier ou dossier

Comment puis-je récupérer la taille d'un dossier ou d'un fichier en Java?

92
demandé sur Frédéric Hamidi 2010-01-27 22:44:41

14 réponses

java.io.File file = new java.io.File("myfile.txt");
file.length();

Ce retourne la taille du fichier en octets ou 0 si le fichier n'existe pas. Il n'y a pas de manière intégrée pour obtenir la taille d'un dossier, vous allez devoir parcourir l'arborescence des répertoires de façon récursive (en utilisant la méthode listFiles() d'un objet fichier qui représente un répertoire) et accumuler la taille du répertoire pour vous-même:

public static long folderSize(File directory) {
    long length = 0;
    for (File file : directory.listFiles()) {
        if (file.isFile())
            length += file.length();
        else
            length += folderSize(file);
    }
    return length;
}

WARNING : cette méthode n'est pas suffisamment robuste pour une utilisation en production. directory.listFiles() peut retourner null et causer un NullPointerException . En outre, il ne considère pas les liens symboliques et peut-être a d'autres modes de défaillance. Utilisez cette méthode .

167
répondu Tendayi Mawushe 2015-10-28 10:43:16

Vous avez besoin de FileUtils#sizeOfDirectory(File) à partir de commons-io .

notez que vous devrez vérifier manuellement si le fichier est un répertoire car la méthode lance une exception si un non-répertoire lui est passé.

WARNING : cette méthode (à partir de commons-io 2.4) a un bug et peut lancer IllegalArgumentException si le répertoire est modifié simultanément.

34
répondu yegor256 2015-10-28 10:37:14

avec l'api NIO java-7, le calcul de la taille du dossier peut être fait beaucoup plus rapidement.

voici un exemple prêt à l'emploi qui est robuste et ne fera pas d'exception. Il va enregistrer les répertoires qu'il ne peut pas entrer ou a eu des difficultés à traverser. Les liens symboliques sont ignorés, et la modification simultanée du répertoire ne causera pas plus de problèmes que nécessaire.

/**
 * Attempts to calculate the size of a file or directory.
 * 
 * <p>
 * Since the operation is non-atomic, the returned value may be inaccurate.
 * However, this method is quick and does its best.
 */
public static long size(Path path) {

    final AtomicLong size = new AtomicLong(0);

    try {
        Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {

                size.addAndGet(attrs.size());
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) {

                System.out.println("skipped: " + file + " (" + exc + ")");
                // Skip folders that can't be traversed
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) {

                if (exc != null)
                    System.out.println("had trouble traversing: " + dir + " (" + exc + ")");
                // Ignore errors traversing a folder
                return FileVisitResult.CONTINUE;
            }
        });
    } catch (IOException e) {
        throw new AssertionError("walkFileTree will not throw IOException if the FileVisitor does not");
    }

    return size.get();
}
33
répondu Aksel Willgert 2016-11-21 07:21:46
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;
}
10
répondu Vishal 2010-01-27 21:36:57

En Java 8:

long size = Files.walk(path).mapToLong( p -> p.toFile().length() ).sum();

il serait plus agréable d'utiliser Files::size dans l'étape de carte, mais il lance une exception cochée.

mise à jour:

Vous devez également être conscient que cela peut jeter une exception si certains fichiers/dossiers ne sont pas accessibles. Voir cette question et une autre solution en utilisant Goyave .

10
répondu Andrejs 2017-05-23 12:10:45

si vous voulez utiliser L'API Java 8 NIO , le programme suivant imprimera la taille, en octets, du répertoire dans lequel il se trouve.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class PathSize {

    public static void main(String[] args) {
        Path path = Paths.get(".");
        long size = calculateSize(path);
        System.out.println(size);
    }

    /**
     * Returns the size, in bytes, of the specified <tt>path</tt>. If the given
     * path is a regular file, trivially its size is returned. Else the path is
     * a directory and its contents are recursively explored, returning the
     * total sum of all files within the directory.
     * <p>
     * If an I/O exception occurs, it is suppressed within this method and
     * <tt>0</tt> is returned as the size of the specified <tt>path</tt>.
     * 
     * @param path path whose size is to be returned
     * @return size of the specified path
     */
    public static long calculateSize(Path path) {
        try {
            if (Files.isRegularFile(path)) {
                return Files.size(path);
            }

            return Files.list(path).mapToLong(PathSize::calculateSize).sum();
        } catch (IOException e) {
            return 0L;
        }
    }

}

la méthode calculateSize est universelle pour les objets Path , donc elle fonctionne aussi pour les fichiers. Note que si un fichier ou un répertoire est inaccessible, dans ce cas, la taille de l'objet path sera 0 .

4
répondu dinomario10 2017-03-04 18:18:03

File.length() ( Javadoc ).

Notez que cela ne fonctionne pas pour les répertoires, ou n'est pas garanti.

Pour un répertoire, que voulez-vous? Si c'est la taille totale de tous les fichiers en dessous, vous pouvez recursively walk children en utilisant File.list() et File.isDirectory() et la somme de leurs tailles.

3
répondu danben 2010-01-27 19:46:57

l'objet File a une méthode length :

f = new File("your/file/name");
f.length();
3
répondu JesperE 2010-01-27 19:47:46

, Voici la meilleure façon d'obtenir un général taille du Fichier (œuvres de répertoire et de la non-répertoire):

public static long getSize(File file) {
    long size;
    if (file.isDirectory()) {
        size = 0;
        for (File child : file.listFiles()) {
            size += getSize(child);
        }
    } else {
        size = file.length();
    }
    return size;
}

Edit: notez que cette opération va probablement prendre beaucoup de temps. Ne l'exécute pas sur le fil D'interface utilisateur.

aussi, ici (tiré de https://stackoverflow.com/a/5599842/1696171 ) est une bonne façon d'obtenir une chaîne de caractères lisible par l'utilisateur à partir des longs retours:

public static String getReadableSize(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];
}
3
répondu Eric Cochran 2017-05-23 11:55:02

Pour Java 8 c'est une bonne façon de le faire:

Files.walk(new File("D:/temp").toPath())
                .map(f -> f.toFile())
                .filter(f -> f.isFile())
                .mapToLong(f -> f.length()).sum()

il est important de filtrer tous les répertoires , parce que la méthode de longueur n'est pas garantie d'être 0 pour les répertoires.

au moins ce code fournit les mêmes informations de taille que Windows Explorer lui-même.

3
répondu wumpz 2017-02-21 14:04:51
  • Travaille pour Android et Java
  • Fonctionne pour les deux dossiers et fichiers
  • contrôle de l'indicateur nul partout où c'est nécessaire
  • Ignore lien symbolique aka "raccourcis 151970920"
  • prêt pour la Production!

code Source:

   public long fileSize(File root) {
        if(root == null){
            return 0;
        }
        if(root.isFile()){
            return root.length();
        }
        try {
            if(isSymlink(root)){
                return 0;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return 0;
        }

        long length = 0;
        File[] files = root.listFiles();
        if(files == null){
            return 0;
        }
        for (File file : files) {
            length += fileSize(file);
        }

        return length;
    }

    private static boolean isSymlink(File file) throws IOException {
        File canon;
        if (file.getParent() == null) {
            canon = file;
        } else {
            File canonDir = file.getParentFile().getCanonicalFile();
            canon = new File(canonDir, file.getName());
        }
        return !canon.getCanonicalFile().equals(canon.getAbsoluteFile());
    }
2
répondu Ilya Gazman 2017-10-15 15:15:49
public long folderSize (String directory)
    {
        File curDir = new File(directory);
        long length = 0;
        for(File f : curDir.listFiles())
        {
            if(f.isDirectory())
            {               
                 for ( File child : f.listFiles()) 
                 {
                     length = length + child.length();
                 }

                System.out.println("Directory: " + f.getName() + " " + length + "kb");
            }
            else
            {
                length = f.length();
                System.out.println("File: " + f.getName() + " " + length + "kb");
            }
            length = 0;
        }
        return length;
    }
0
répondu Nicholas 2014-10-05 18:49:16

après de nombreuses recherches et recherches sur les différentes solutions proposées ici à StackOverflow. J'ai finalement décidé d'écrire mon propre solution. Mon but est d'avoir un mécanisme sans lancer parce que je ne veux pas me planter si L'API est incapable de récupérer la taille du dossier. cette méthode ne convient pas au scénario à filetage multiple.

tout d'abord, je veux vérifier les répertoires valides tout en parcourant l'arborescence du système de fichiers.

private static boolean isValidDir(File dir){
    if (dir != null && dir.exists() && dir.isDirectory()){
        return true;
    }else{
        return false;
    }
}

Deuxième je ne veux pas que mon appel récursif à aller dans les liens symboliques (softlinks) et incluent la taille totale de l'agrégat.

public static boolean isSymlink(File file) throws IOException {
    File canon;
    if (file.getParent() == null) {
        canon = file;
    } else {
        canon = new File(file.getParentFile().getCanonicalFile(),
                file.getName());
    }
    return !canon.getCanonicalFile().equals(canon.getAbsoluteFile());
}

enfin mon implémentation basée sur la récursion pour récupérer la taille du répertoire spécifié. Notez la vérification nulle pour dir.listFiles(). Selon javadoc il y a une possibilité que cette méthode puisse retourner null.

public static long getDirSize(File dir){
    if (!isValidDir(dir))
        return 0L;
    File[] files = dir.listFiles();
    //Guard for null pointer exception on files
    if (files == null){
        return 0L;
    }else{
        long size = 0L;
        for(File file : files){
            if (file.isFile()){
                size += file.length();
            }else{
                try{
                    if (!isSymlink(file)) size += getDirSize(file);
                }catch (IOException ioe){
                    //digest exception
                }
            }
        }
        return size;
    }
}

un peu de crème sur le gâteau, L'API pour obtenir la taille des fichiers de liste (peut-être tous les fichiers et dossiers sous root).

public static long getDirSize(List<File> files){
    long size = 0L;
    for(File file : files){
        if (file.isDirectory()){
            size += getDirSize(file);
        } else {
            size += file.length();
        }
    }
    return size;
}
0
répondu A.B. 2017-01-21 16:23:05

sous linux, si vous voulez trier les répertoires puis du-sh * | sort-h

0
répondu Prem S 2017-03-31 19:27:42