Java Directory Size

Java Directory Size

In this post, we will learn how to get the Java directory size or size of a folder in Java using Java 7, Java 8 and Apache Commons API.

 

1.  Get Size Using Java 7

We will be using Files.walkFileTree() method to recursively transverse through the files/directory to calculate the size.

public class DirectorySizeJava7 {

    public static void main(String[] args) throws IOException {

        Path rootDirectory= Paths.get("/Users/umesh/personal/tutorials/source/bootstrap");
        AtomicLong size= new AtomicLong(0);

        Files.walkFileTree(rootDirectory, new SimpleFileVisitor<Path>(){

            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                    throws IOException{

                 size.addAndGet(attrs.size());
                return  FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exception)
                    throws IOException
            {
               //log exception
                throw exception;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exception) {

                //log exception for error in reading file if exception is not null
                return FileVisitResult.CONTINUE;
            }

        });

        System.out.println("size of the folder is :: " + size);
    }

}

Output

the size of the folder is:: 1650691

I have used AtomicLong in above example to store size, which guarantees that the value can be used in a concurrent environment.

 

2.  Get Size Using Java 8

We will be using  Stream API along with Lambda expression provided by Java 8 to calculate the size of the folder.

public class DirectorySizeJava8 {

    public static void main(String[] args) throws IOException {

        Path rootDirectory = Paths.get("/Users/umesh/personal/tutorials/source/bootstrap");

        long directorySize = Files.walk(rootDirectory)
                .map(f -> f.toFile())
                .filter(f -> f.isFile())
                .mapToLong(f -> f.length()).sum();
    }
}

 

We used stream API and making sure to filter out all directories by using filter(f -> f.isFile()). Please be aware that length method is not guaranteed to be 0 for directories. 

We converted the result to LongStream by using mapToLong method and finally summed up the results to get the size.

Output

the size of the directory is::1650691

Note

Keep in mind following information while using  walkFileTree or walk method under Java 7 and Java 8

  1. Underlying Java Security Manager can throw an exception in case we do not have permission to access it.
  2. Symbolic links can lead to infinite loop issue.

 

3.  Get Size Using Apache Commons

Apache Commons IO’s FileUtils class provide a clean way to calculate the size of a given directory.

public class DirectorySizeApacheCommons {

    public static void main(String[] args) {

        File rootDirectory = new File("/Users/umesh/personal/tutorials/source/bootstrap");
        long size= FileUtils.sizeOfDirectory(rootDirectory);

        System.out.println("The Size of directory is:: "+size);
    }

}

Output

The Size of directory is:: 1650691

You need to be aware of the following 

  1. You have to check if the file is directory else API will throw IllegalArgumentException.
  2. It might also throw IllegalArgumentException if the directory is being concurrently modified. Check IO-449.

 

4.  Get Size Readable format

Printing information in human readable format is always a preferred way. Here is a small programme to print size information obtained in this post in human readable format.

public class DirectorySizeApacheCommons {

    public static void main(String[] args) {

        File rootDirectory = new File("/Users/umesh/personal/tutorials/source/bootstrap");
        long size= FileUtils.sizeOfDirectory(rootDirectory);
        readableFileSize(size);
    }

    public static void readableFileSize(long size){
        final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" };
        int unitGroups = (int) (Math.log10(size)/Math.log10(1024));
        System.out.println(new DecimalFormat("#,##0.#").format(size/Math.pow(1024, unitGroups)) + " " + units[unitGroups]);
    }

}

All the code of this article is available Over on Github. This is a Maven-based project.

References

Apache Commons IO

DecimalFormat

AtomicLong