Obtenir la taille du dossier ou du fichier

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

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

Cela renvoie la longueur du fichier en octets ou 0 si le fichier n’existe pas. Il n’y a pas de moyen intégré pour obtenir la taille d’un dossier, vous devrez parcourir l’arborescence de manière récursive (en utilisant la méthode listFiles() d’un object fichier représentant 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; } 

ATTENTION : Cette méthode n’est pas suffisamment robuste pour une utilisation en production. directory.listFiles() peut renvoyer null et provoquer une NullPointerException . En outre, il ne prend pas en compte les liens symboliques et peut-être d’autres modes de défaillance. Utilisez cette méthode .

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

Notez que vous devrez vérifier manuellement si le fichier est un répertoire car la méthode lève une exception si un non-répertoire lui est transmis.

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

En utilisant java-7 nio api, le calcul de la taille du dossier peut être effectué beaucoup plus rapidement.

Voici un exemple prêt à fonctionner qui est robuste et qui ne lancera pas d’exception. Il enregistrera les répertoires dans lesquels il ne peut pas entrer ou a du mal à se déplacer. 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. * * 

* 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() { @Override public FileVisitResult visitFile(Path file, BasicFileAtsortingbutes 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(); }

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

Dans Java 8:

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

Il serait préférable d’utiliser Files::size dans l’étape de la carte, mais cela génère une exception vérifiée.

METTRE À JOUR:
Vous devez également savoir que cela peut générer une exception si certains fichiers / dossiers ne sont pas accessibles. Voir cette question et une autre solution utilisant Guava .

File.length() ( Javadoc ).

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

Pour un répertoire, que voulez-vous? Si la taille totale de tous les fichiers se trouve en dessous, vous pouvez parcourir récursivement les enfants à l’aide de File.list() et File.isDirectory() et additionner leurs tailles.

L’object File a une méthode de length :

 f = new File("your/file/name"); f.length(); 

Voici la meilleure façon d’obtenir une taille de fichier générale (fonctionne pour répertoire et 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 cela va probablement être une opération fastidieuse. Ne l’exécutez pas sur le thread d’interface utilisateur.

En outre, ici (extrait de https://stackoverflow.com/a/5599842/1696171 ), vous pouvez obtenir une chaîne lisible par l’utilisateur à partir du long rendu:

 public static Ssortingng 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]; } 

Pour Java 8, c’est une bonne façon de procéder:

 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 , car la méthode length n’est pas forcément égale à 0 pour les répertoires.

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

Si vous souhaitez 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(Ssortingng[] args) { Path path = Paths.get("."); long size = calculateSize(path); System.out.println(size); } /** * Returns the size, in bytes, of the specified path. If the given * path is a regular file, sortingvially 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. * 

* If an I/O exception occurs, it is suppressed within this method and * 0 is returned as the size of the specified path. * * @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 étant universelle pour les objects Path , elle fonctionne également pour les fichiers. Notez que si un fichier ou un répertoire est inaccessible, dans ce cas la taille renvoyée de l’object chemin sera 0 .

  • Fonctionne pour Android et Java
  • Fonctionne à la fois pour les dossiers et les fichiers
  • Vérifie le pointeur nul partout où cela est nécessaire
  • Ignore le lien symbolique aka raccourcis
  • Production prête!

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()); } 
 public long folderSize (Ssortingng 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; } 

Après beaucoup de recherches et de recherches sur les différentes solutions proposées ici à StackOverflow. J’ai finalement décidé d’écrire ma propre solution. Mon but est d’avoir un mécanisme de non-lancement car je ne veux pas tomber en panne si l’API ne parvient pas à récupérer la taille du dossier. Cette méthode ne convient pas pour un scénario multithread.

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èmement, je ne veux pas que mon appel récursif entre dans des liens symboliques (liens logiciels) et inclue la taille dans l’agrégat total.

 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écursivité pour récupérer la taille du répertoire spécifié. Notez la vérification null pour dir.listFiles (). Selon javadoc, il est possible que cette méthode renvoie 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 de la liste des fichiers (peut être tous les fichiers et le dossier sous la racine).

 public static long getDirSize(List files){ long size = 0L; for(File file : files){ if (file.isDirectory()){ size += getDirSize(file); } else { size += file.length(); } } return size; } 

dans linux si vous voulez sortinger les répertoires puis du -hs * | sortinger -h