1. Overview
In this tutorial – we’ll learn how to get 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 – lets 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 is 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.
- 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 an Eclipse based project, so it should be easy to import and run as it is.
Java 8 is out and about now - to keep track of everything, I will keep updating the Gran Kahuna of Java 8 Resources.