Java - Размер каталога
1. обзор
В этом руководстве мы узнаем, как получитьsize of a folder in Java, используя Java 6, 7 и новую Java 8, а также Guava и Apache Common IO.
Наконец, мы также получим удобочитаемое представление о размере каталога.
2. С Java
Начнем с простого примера расчета размера папки -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;
}
Мы можем протестировать наш методgetFolderSize(), как в следующем примере:
@Test
public void whenGetFolderSizeRecursive_thenCorrect() {
long expectedSize = 12607;
File folder = new File("src/test/resources");
long size = getFolderSize(folder);
assertEquals(expectedSize, size);
}
Примечание:listFiles() используется для отображения содержимого данной папки.
3. С Java 7
Далее - давайте посмотрим, как использоватьJava 7 to get the folder size. В следующем примере мы используем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() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
size.addAndGet(attrs.size());
return FileVisitResult.CONTINUE;
}
});
assertEquals(expectedSize, size.longValue());
}
Обратите внимание на то, как мы используем возможности обхода дерева файловой системы здесь и используем шаблон посетителя, чтобы помочь нам посетить и вычислить размеры каждого файла и подпапки.
4. С Java 8
А теперь давайте посмотрим, как получить размер папки с помощьюJava 8, stream operations and 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);
}
Примечание:mapToLong() используется для генерацииLongStream путем применения функцииlength в каждом элементе - после чего мы можемsum и получить окончательный результат.
5. С Apache Commons IO
Далее - давайте посмотрим, как получить размер папки с помощью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);
}
Обратите внимание, что этот метод утилиты указывает на простое решение Java 6 под капотом.
Также обратите внимание, что библиотека также предоставляет методFileUtils.sizeOfDirectoryAsBigInteger(), который лучше справляется с каталогами с ограниченным доступом.
6. С гуавой
А теперь давайте посмотрим, как рассчитать размер папки с помощьюGuava. В следующем примере мы используемFiles.fileTreeTraverser() для обхода всех файлов в папке, чтобы суммировать их размер:
@Test
public void whenGetFolderSizeUsingGuava_thenCorrect() {
long expectedSize = 12607;
File folder = new File("src/test/resources");
Iterable files = Files.fileTreeTraverser()
.breadthFirstTraversal(folder);
long size = StreamSupport.stream(files.spliterator(), false)
.filter(f -> f.isFile())
.mapToLong(File::length).sum();
assertEquals(expectedSize, size);
}
7. Удобочитаемый размер
Наконец, давайте посмотрим, как получить более удобочитаемое представление размера папки, а не просто размер в байтах:
@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);
}
Примечание. Мы использовалиDecimalFormat(“,#0,#”), чтобы округлить результат до одного десятичного знака.
8. Заметки
Вот некоторые заметки о расчете размера папки:
-
ИFiles.walk(), иFiles.walkFileTree() вызовут исключение SecurityException, если диспетчер безопасности запрещает доступ к начальному файлу.
-
Бесконечный цикл может возникнуть, если папка содержит символические ссылки.
9. Заключение
В этом кратком руководстве мы проиллюстрировали примеры использования различных версийJava,Apache Commons IO иGuava для расчета размера каталога в файловой системе.
Реализацию этих примеров можно найти вthe GitHub project - это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.