Иногда требуется узнать размер директории на файловой системе. В Java это можно сделать несколькими способами — с помощью стандартного API и внешних библиотек.

Здесь мы рассмотрим различные способы узнать размер директории:

  • Используя сторонню библиотеку Apache Commons IO (FileUtils.sizeOfDirectory)
  • Используя стандартную библиотеку Java 8 (Files.walk)
  • Используя стандартную библиотеку Java 7 (FileVisitor)
  • Используя стандартную библиотеку Java 6

1. Размер директории с помощью Apache Commons IO

Это наиболее простой в использовании способ — достаточно воспользоваться одним методом из этой библиотеки. Но сначала её требуется подключить к проекту:

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.7</version>
        </dependency>

После этого, воспользуемся методом sizeOfDirectory:

FileUtils.sizeOfDirectory(new File("/home/alex/java-lessons.ru"));

В ответ вернётся размер директории в байтах:

2. Размер директории с помощью Files.walk (Java 8+)

Если вы не хотите подключать сторонние библиотеки, можно воспользоваться стандартным API. В Java 8 появился метод Files.walk, с помощью которого можно обойти все файлы в директории и подсчитать их размер:

Path path = Paths.get("/home/alex/java-lessons.ru");

long size = 0;

try (Stream<Path> walk = Files.walk(path)) {

    size = walk
            .filter(Files::isRegularFile)
            .mapToLong(p -> {
                try {
                    return Files.size(p);
                } catch (IOException e) {
                    System.out.printf("Невозможно получить размер файла %s%n%s", p, e);
                    return 0L;
                }
            })
            .sum();

} catch (IOException e) {
    System.out.printf("Ошибка при подсчёте размера директории %s", e);
}

System.out.println(size);

3. Размер директории с помощью FileVisitor (Java 7+)

Если вы используете Java 7, вы можете воспользоваться стандартным FileVisitor:

Path path = Paths.get("/home/alex/java-lessons.ru");

AtomicLong size = new AtomicLong(0);

try {

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

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            // sum size of all visit file
            size.addAndGet(attrs.size());
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path file, IOException e) throws IOException {
            System.out.printf("Невозможно получить размер файла %s%n%s", file, e);
            return FileVisitResult.CONTINUE;
        }

    });
} catch (IOException e) {
    System.out.printf("Ошибка при подсчёте размера директории %s", e);
}

System.out.println(size);

Здесь принцип тот же, что и в примере с Files.walk — приходится обходить все файлы в директории и подсчитывать их размер.

3. Размер директории с помощью FileVisitor (Java 6+)

Если же вы располагает Java 6, для подсчёта размера всех вложенных файлов придётся рекурсивно итерироваться по директориям:

public static long getDirectorySizeJava6(File dir) {
    long length = 0;
    File[] files = dir.listFiles();
    if (files != null) {
        for (File file : files) {
            if (file.isFile())
                length += file.length();
            else
                length += getDirectorySizeJava6(file);
        }
    }
    return length;
}

Исходный код

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Stream;

public class GetFolderSize {

    public static void main(String[] args) {
        System.out.println(getDirectorySizeJava8("/home/alex/java-lessons.ru"));
    }

    public static long getDirectorySizeApache(String path) {
        return FileUtils.sizeOfDirectory(new File(path));
    }

    public static long getDirectorySizeJava8(String s) {
        Path path = Paths.get(s);

        long size = 0;

        try (Stream<Path> walk = Files.walk(path)) {

            size = walk
                    .filter(Files::isRegularFile)
                    .mapToLong(p -> {
                        try {
                            return Files.size(p);
                        } catch (IOException e) {
                            System.out.printf("Невозможно получить размер файла %s%n%s", p, e);
                            return 0L;
                        }
                    })
                    .sum();

        } catch (IOException e) {
            System.out.printf("Ошибка при подсчёте размера директории %s", e);
        }

        return size;
    }

    public static long getDirectorySizeJava7(String s) {
        Path path = Paths.get(s);

        AtomicLong size = new AtomicLong(0);

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

                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    // sum size of all visit file
                    size.addAndGet(attrs.size());
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFileFailed(Path file, IOException e) throws IOException {
                    System.out.printf("Невозможно получить размер файла %s%n%s", file, e);
                    return FileVisitResult.CONTINUE;
                }
            });
        } catch (IOException e) {
            System.out.printf("Ошибка при подсчёте размера директории %s", e);
        }

        return size.get();
    }


    public static long getDirectorySizeJava6(File dir) {
        long length = 0;
        File[] files = dir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile())
                    length += file.length();
                else
                    length += getDirectorySizeJava6(file);
            }
        }
        return length;
    }
}

Заключение

Для подсчёта размера директории подходят несколько способов — с подключением сторонних библиотек и с использованием стандартного API в Java. Сторонние библиотеки обычно предоставляют удобный в использовании метод, который скрывает весь шаблонный код по обходу дерева файлов. А со стандартным API придётся повозиться, но зато у вас в проекте не будет ещё одной зависимости в виде сторонней библиотеки.

Как узнать размер директории