Java - Taille du répertoire

Java - Taille du répertoire

1. Vue d'ensemble

Dans ce didacticiel - nous allons apprendre à obtenir lessize of a folder in Java - en utilisant Java 6, 7 et le nouveau Java 8 ainsi que Guava et Apache Common IO.

Enfin, nous obtiendrons également une représentation lisible par l’homme de la taille du répertoire.

2. Avec Java

Commençons par un exemple simple de calcul de la taille d'un dossier -using the sum of its contents:

private long getFolderSize(File folder) {
    long length = 0;
    File[] files = folder.listFiles();

    int count = files.length;

    for (int i = 0; i < count; i++) {
        if (files[i].isFile()) {
            length += files[i].length();
        }
        else {
            length += getFolderSize(files[i]);
        }
    }
    return length;
}

Nous pouvons tester notre méthodegetFolderSize() comme dans l'exemple suivant:

@Test
public void whenGetFolderSizeRecursive_thenCorrect() {
    long expectedSize = 12607;

    File folder = new File("src/test/resources");
    long size = getFolderSize(folder);

    assertEquals(expectedSize, size);
}

Remarque:listFiles() est utilisé pour lister le contenu du dossier donné.

3. Avec Java 7

Ensuite, voyons comment utiliserJava 7 to get the folder size. Dans l'exemple suivant, nous utilisonsFiles.walkFileTree() pour parcourir tous les fichiers du dossier pour additionner leurs tailles:

@Test
public void whenGetFolderSizeUsingJava7_thenCorrect() throws IOException {
    long expectedSize = 12607;

    AtomicLong size = new AtomicLong(0);
    Path folder = Paths.get("src/test/resources");

    Files.walkFileTree(folder, new SimpleFileVisitor() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
          throws IOException {
            size.addAndGet(attrs.size());
            return FileVisitResult.CONTINUE;
        }
    });

    assertEquals(expectedSize, size.longValue());
}

Notez comment nous exploitons les capacités de traversée de l'arborescence du système de fichiers ici et utilisons le modèle de visiteur pour nous aider à visiter et à calculer la taille de chaque fichier et sous-dossier.

4. Avec Java 8

Voyons maintenant comment obtenir la taille du dossier en utilisantJava 8, stream operations and lambdas. Dans l'exemple suivant, nous utilisonsFiles.walk() pour parcourir tous les fichiers du dossier pour additionner leur taille:

@Test
public void whenGetFolderSizeUsingJava8_thenCorrect() throws IOException {
    long expectedSize = 12607;

    Path folder = Paths.get("src/test/resources");
    long size = Files.walk(folder)
      .filter(p -> p.toFile().isFile())
      .mapToLong(p -> p.toFile().length())
      .sum();

    assertEquals(expectedSize, size);
}

Remarque:mapToLong() est utilisé pour générer unLongStream en appliquant la fonctionlength dans chaque élément - après quoi nous pouvonssum et obtenir un résultat final.

5. Avec Apache Commons IO

Ensuite, voyons comment obtenir la taille du dossier en utilisantApache Commons IO. Dans l'exemple suivant, nous utilisons simplementFileUtils.sizeOfDirectory() pour obtenir la taille du dossier:

@Test
public void whenGetFolderSizeUsingApacheCommonsIO_thenCorrect() {
    long expectedSize = 12607;

    File folder = new File("src/test/resources");
    long size = FileUtils.sizeOfDirectory(folder);

    assertEquals(expectedSize, size);
}

Notez que cette méthode utilitaire au point implémente une solution Java 6 simple sous le capot.

Notez également que la bibliothèque fournit également une méthodeFileUtils.sizeOfDirectoryAsBigInteger() qui traite mieux les répertoires à sécurité limitée.

6. Avec goyave

Voyons maintenant comment calculer la taille d'un dossier à l'aide deGuava. Dans l'exemple suivant, nous utilisonsFiles.fileTreeTraverser() pour parcourir tous les fichiers du dossier pour additionner leur taille:

@Test
public void whenGetFolderSizeUsingGuava_thenCorrect() {
    long expectedSize = 12607;

    File folder = new File("src/test/resources");

    Iterable files = Files.fileTreeTraverser()
          .breadthFirstTraversal(folder);
    long size = StreamSupport.stream(files.spliterator(), false)
      .filter(f -> f.isFile())
      .mapToLong(File::length).sum();

    assertEquals(expectedSize, size);
}

7. Taille lisible par l'homme

Enfin, voyons comment obtenir une représentation plus lisible par l'utilisateur de la taille du dossier, et pas seulement une taille en octets:

@Test
public void whenGetReadableSize_thenCorrect() {
    File folder = new File("src/test/resources");
    long size = getFolderSize(folder);

    String[] units = new String[] { "B", "KB", "MB", "GB", "TB" };
    int unitIndex = (int) (Math.log10(size) / 3);
    double unitValue = 1 << (unitIndex * 10);

    String readableSize = new DecimalFormat("#,##0.#")
                                .format(size / unitValue) + " "
                                + units[unitIndex];
    assertEquals("12.3 KB", readableSize);
}

Remarque: Nous avons utiliséDecimalFormat(“,#0,#”) pour arrondir le résultat à une décimale.

8. Remarques

Voici quelques notes sur le calcul de la taille du dossier:

  • LesFiles.walk() etFiles.walkFileTree() lèveront une SecurityException si le gestionnaire de sécurité refuse l'accès au fichier de départ.

  • La boucle infinie peut se produire si le dossier contient des liens symboliques.

9. Conclusion

Dans ce tutoriel rapide, nous avons illustré des exemples d'utilisation de différentes versions deJava,Apache Commons IO etGuava pour calculer la taille d'un répertoire dans le système de fichiers.

L'implémentation de ces exemples peut être trouvée dansthe GitHub project - il s'agit d'un projet basé sur Maven, il devrait donc être facile à importer et à exécuter tel quel.