1. Обзор
В этом руководстве мы узнаем, как получить размер папки в 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 SimpleFileVisitor<Path>() {
@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");
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. Удобочитаемый размер
Наконец, давайте посмотрим, как получить более удобочитаемое представление размера папки, а не только размер в байтах:
@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, поэтому его легко импортировать и запускать как есть.