Java – Directory Size – Java – 目录大小

最后修改: 2014年 11月 20日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

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.

在本教程中,我们将学习如何在Java中获取文件夹的大小 – 使用Java 6、7和新的Java 8以及Guava和Apache Common IO。

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

最后–我们还将得到一个人类可读的目录大小表示。

2. With Java

2.使用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:

我们可以测试我们的方法getFolderSize(),如下面的例子。

@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.

注意:listFiles()用于列出指定文件夹的内容。

3. With Java 7

3.使用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:

接下来–让我们看看如何使用Java 7来获取文件夹的大小。在下面的例子中–我们使用Files.walkFileTree()来遍历文件夹中的所有文件,以总结其大小。

@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

4.使用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:

现在–让我们看看如何使用Java 8、流操作和lambdas获得文件夹的大小。在下面的例子中–我们使用Files.walk()来遍历文件夹中的所有文件,以总结它们的大小。

@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.

注意:mapToLong()用于通过在每个元素中应用length函数来生成LongStream–之后我们可以sum并得到一个最终结果。

5. With Apache Commons IO

5.使用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:

接下来–让我们看看如何使用Apache Commons IO获得文件夹的大小。在下面的例子中,我们简单地使用FileUtils.sizeOfDirectory()来获取文件夹的大小。

@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.

请注意,这个到点子上的实用方法实现了一个简单的Java 6解决方案。

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

另外,请注意,该库还提供了一个FileUtils.sizeOfDirectoryAsBigInteger()方法,可以更好地处理安全限制的目录。

6. With Guava

6.有番石榴

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:

现在–让我们看看如何用Guava计算一个文件夹的大小。在下面的例子中–我们使用Files.fileTreeTraverser()来遍历文件夹中的所有文件,以总结它们的大小。

@Test public void whenGetFolderSizeUsingGuava_thenCorrect() { 
    long expectedSize = 12607; 
    File folder = new File("src/test/resources"); 
   
    Iterable<File> files = Files.fileTraverser().breadthFirst(folder);
    long size = StreamSupport.stream(files.spliterator(), false) .filter(f -> f.isFile()) 
      .mapToLong(File::length).sum(); 
   
    assertEquals(expectedSize, size); 
}

7. Human Readable Size

7.人类可读的尺寸

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.

注意:我们使用DecimalFormat(“#,##0,#”)将结果四舍五入到一个小数位。

8. Notes

8.注意

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

9.结论

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.

在这个快速教程中,我们举例说明了使用不同的Java版本、Apache Commons IOGuava来计算文件系统中一个目录的大小。

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.

这些例子的实现可以在GitHub项目中找到–这是一个基于Maven的项目,所以应该很容易导入并按原样运行。