Java – Directory Size

https://stackoverflow.com/questions/2149785/get-size-of-folder-or-file/19877372#19877372

原文鏈接:http://www.baeldung.com/java-folder-size

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
privatelong getFolderSize(File folder) {
    longlength = 0;
    File[] files = folder.listFiles();
 
    intcount = files.length;
 
    for(inti = 0; i < count; i++) {
        if(files[i].isFile()) {
            length += files[i].length();
        }
        else{
            length += getFolderSize(files[i]);
        }
    }
    returnlength;
}

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

1
2
3
4
5
6
7
8
9
@Test
publicvoid whenGetFolderSizeRecursive_thenCorrect() {
    longexpectedSize = 12607;
 
    File folder = newFile("src/test/resources");
    longsize = 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
publicvoid whenGetFolderSizeUsingJava7_thenCorrect() throwsIOException {
    longexpectedSize = 12607;
 
    AtomicLong size = newAtomicLong(0);
    Path folder = Paths.get("src/test/resources");
 
    Files.walkFileTree(folder,newSimpleFileVisitor<Path>() {
        @Override
        publicFileVisitResult visitFile(Path file, BasicFileAttributes attrs)
          throwsIOException {
            size.addAndGet(attrs.size());
            returnFileVisitResult.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:

1
2
3
4
5
6
7
8
9
10
11
12
@Test
publicvoid whenGetFolderSizeUsingJava8_thenCorrect() throwsIOException {
    longexpectedSize = 12607;
 
    Path folder = Paths.get("src/test/resources");
    longsize = 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:

1
2
3
4
5
6
7
8
9
@Test
publicvoid whenGetFolderSizeUsingApacheCommonsIO_thenCorrect() {
    longexpectedSize = 12607;
 
    File folder = newFile("src/test/resources");
    longsize = 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
publicvoid whenGetFolderSizeUsingGuava_thenCorrect() {
    longexpectedSize = 12607;
 
    File folder = newFile("src/test/resources");
 
    Iterable<File> files = Files.fileTreeTraverser()
                                .breadthFirstTraversal(folder);
    longsize = 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
publicvoid whenGetReadableSize_thenCorrect() {
    File folder = newFile("src/test/resources");
    longsize = getFolderSize(folder);
 
    String[] units = newString[] { "B","KB","MB","GB","TB"};
    intunitIndex = (int) (Math.log10(size) / 3);
    doubleunitValue = 1<< (unitIndex * 10);
 
    String readableSize = newDecimalFormat("#,##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 an Eclipse based project, so it should be easy to import and run as it is.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章