Java — размер каталога
В этом руководстве мы узнаем, как получить размер папки в Java , используя Java 6, 7 и новую Java 8, а также Guava и Apache Common IO.
Наконец, мы также получим удобочитаемое представление размера каталога.
2. С Явой
Начнем с простого примера вычисления размера папки — с использованием суммы ее содержимого :
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 для получения размера папки . В следующем примере мы используем 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 SimpleFileVisitorPath>() @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, потоковых операций и лямбда-выражений . В следующем примере мы используем 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 путем применения функции длины к каждому элементу, после чего мы можем просуммировать и получить окончательный результат.
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"); IterableFile> files = Files.fileTraverser().breadthFirst(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 для расчета размера каталога в файловой системе.
Реализацию этих примеров можно найти в проекте GitHub — это проект на основе Maven, поэтому его легко импортировать и запускать как есть.
Как узнать размер директории
Иногда требуется узнать размер директории на файловой системе. В Java это можно сделать несколькими способами — с помощью стандартного API и внешних библиотек.
Здесь мы рассмотрим различные способы узнать размер директории:
- Используя сторонню библиотеку Apache Commons IO (FileUtils.sizeOfDirectory)
- Используя стандартную библиотеку Java 8 (Files.walk)
- Используя стандартную библиотеку Java 7 (FileVisitor)
- Используя стандартную библиотеку Java 6
1. Размер директории с помощью Apache Commons IO
Это наиболее простой в использовании способ — достаточно воспользоваться одним методом из этой библиотеки. Но сначала её требуется подключить к проекту:
После этого, воспользуемся методом 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 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() < @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 (Streamwalk = 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() < @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 — Размер каталога
В этом руководстве мы узнаем, как получить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"); Iterablefiles = 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
Примечание. Мы использовалиDecimalFormat(“ , #0,#”), чтобы округлить результат до одного десятичного знака.
8. Заметки
Вот некоторые заметки о расчете размера папки:
- ИFiles.walk(), иFiles.walkFileTree() вызовут исключение SecurityException, если диспетчер безопасности запрещает доступ к начальному файлу.
- Бесконечный цикл может возникнуть, если папка содержит символические ссылки.
9. Заключение
В этом кратком руководстве мы проиллюстрировали примеры использования различных версийJava,Apache Commons IO иGuava для расчета размера каталога в файловой системе.
Реализацию этих примеров можно найти вthe GitHub project — это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.