I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial – we’ll learn how to get the size of a folder in Java – using Java 6, 7 and the new Java 8 as well Guava and Apache Common IO.

Finally – we will also get a human-readable representation of the directory size.

2. With Java

Let’s start with a simple example of calculating the size of a folder – 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;
}

We can test our method getFolderSize() as in the following example:

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

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

    assertEquals(expectedSize, size);
}

Note: listFiles() is used to list the contents of the given folder.

3. With Java 7

Next – let’s see how to use Java 7 to get the folder size. In the following example – we use Files.walkFileTree() to traverse all files in the folder to sum their sizes:

@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<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
          throws IOException {
            size.addAndGet(attrs.size());
            return FileVisitResult.CONTINUE;
        }
    });

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

Note how we’re leveraging the filesystem tree traversal capabilities here and making use of the visitor pattern to help us visit and calculate the sizes of each file and subfolder.

4. With Java 8

Now – let’s see how to get the folder size using Java 8, stream operations and lambdas. In the following example – we use Files.walk() to traverse all files in the folder to sum their size:

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

Note: mapToLong() is used to generate a LongStream by applying the length function in each element – after which we can sum and get a final result.

5. With Apache Commons IO

Next – let’s see how to get the folder size using Apache Commons IO. In the following example – we simply use FileUtils.sizeOfDirectory() to get the folder size:

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

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

    assertEquals(expectedSize, size);
}

Note that this to the point utility method implements a simple Java 6 solution under the hood.

Also, note that the library also provides a FileUtils.sizeOfDirectoryAsBigInteger() method that deals with security restricted directories better.

6. With Guava

Now – let’s see how to calculate the size of a folder using Guava. In the following example – we use Files.fileTreeTraverser() to traverse all files in the folder to sum their size:

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

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

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

    assertEquals(expectedSize, size);
}

7. Human Readable Size

Finally – let’s see how to get a more user readable representation of the folder size – not just a size in bytes:

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

Note: We used DecimalFormat(“#,##0,#”) to round the result into one decimal place.

8. Notes

Here are some notes about folder size calculation:

  • Both Files.walk() and Files.walkFileTree() will throw a SecurityException if the security manager denies access to the starting file.
  • The infinite loop may occur if the folder contains symbolic links.

9. Conclusion

In this quick tutorial, we illustrated examples of using different Java versions, Apache Commons IO and Guava to calculate the size of a directory in the file system.

The implementation of these examples can be found in the GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE LESSONS