Java - Verzeichnisgröße

Java - Verzeichnisgröße

1. Überblick

In diesem Tutorial erfahren Sie, wie Sie diesize of a folder in Java erhalten - mit Java 6, 7 und dem neuen Java 8 sowie Guava und Apache Common IO.

Schließlich erhalten wir auch eine lesbare Darstellung der Verzeichnisgröße.

2. Mit Java

Beginnen wir mit einem einfachen Beispiel für die Berechnung der Größe eines Ordners -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;
}

Wir können unsere MethodegetFolderSize() wie im folgenden Beispiel testen:

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

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

    assertEquals(expectedSize, size);
}

Hinweis:listFiles() wird verwendet, um den Inhalt des angegebenen Ordners aufzulisten.

3. Mit Java 7

Weiter - sehen wir uns an, wieJava 7 to get the folder size verwendet werden. Im folgenden Beispiel verwenden wirFiles.walkFileTree(), um alle Dateien im Ordner zu durchlaufen und ihre Größe zu summieren:

@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());
}

Beachten Sie, wie wir hier die Funktionen zum Durchlaufen des Dateisystembaums nutzen und das Besuchermuster verwenden, um die Größe jeder Datei und jedes Unterordners zu ermitteln und zu berechnen.

4. Mit Java 8

Nun wollen wir sehen, wie Sie die Ordnergröße mitJava 8, stream operations and lambdas ermitteln. Im folgenden Beispiel verwenden wirFiles.walk(), um alle Dateien im Ordner zu durchlaufen und ihre Größe zu summieren:

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

Hinweis:mapToLong() wird verwendet, umLongStream durch Anwenden der Funktionlength in jedem Element zu generieren. Danach können wirsum und ein Endergebnis erhalten.

5. Mit Apache Commons IO

Weiter - sehen wir uns an, wie Sie die Ordnergröße mitApache Commons IO ermitteln. Im folgenden Beispiel verwenden wir einfachFileUtils.sizeOfDirectory(), um die Ordnergröße zu ermitteln:

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

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

    assertEquals(expectedSize, size);
}

Beachten Sie, dass diese nützliche Methode eine einfache Java 6-Lösung unter der Haube implementiert.

Beachten Sie außerdem, dass die Bibliothek auch eineFileUtils.sizeOfDirectoryAsBigInteger()-Methode bereitstellt, mit der sicherheitsbeschränkte Verzeichnisse besser behandelt werden können.

6. Mit Guave

Nun sehen wir uns an, wie Sie die Größe eines Ordners mitGuava berechnen. Im folgenden Beispiel verwenden wirFiles.fileTreeTraverser(), um alle Dateien im Ordner zu durchlaufen und ihre Größe zu summieren:

@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. Vom Menschen lesbare Größe

Lassen Sie uns abschließend sehen, wie Sie eine besser lesbare Darstellung der Ordnergröße erhalten - nicht nur eine Größe in Byte:

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

Hinweis: Wir habenDecimalFormat(“,#0,#”) verwendet, um das Ergebnis auf eine Dezimalstelle zu runden.

8. Anmerkungen

Hier einige Hinweise zur Berechnung der Ordnergröße:

  • SowohlFiles.walk() als auchFiles.walkFileTree() lösen eine SecurityException aus, wenn der Sicherheitsmanager den Zugriff auf die Startdatei verweigert.

  • Die Endlosschleife kann auftreten, wenn der Ordner symbolische Links enthält.

9. Fazit

In diesem kurzen Tutorial haben wir Beispiele für die Verwendung verschiedenerJava-Versionen,Apache Commons IO undGuava veranschaulicht, um die Größe eines Verzeichnisses im Dateisystem zu berechnen.

Die Implementierung dieser Beispiele finden Sie inthe GitHub project - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.