Как узнать размер директории
[Как узнать размер директории]
Иногда требуется узнать размер директории на файловой системе. В 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 придётся повозиться, но зато у вас в проекте не будет ещё одной зависимости в виде сторонней библиотеки.
Как узнать размер директории
Интересно узнать, что для определения размера директории в Java можно использовать как стандартные библиотеки, так и внешние инструменты, включая Apache Commons IO. Выбор метода зависит от удобства и требований проекта.