Java - Розмір каталогу

1. Огляд

У цьому підручнику ми дізнаємось, як отримати розмір папки на Java - за допомогою Java 6, 7 та нової Java 8, а також Guava та Apache Common IO.

Нарешті - ми також отримаємо зручне для читання подання розміру каталогу.

2. За допомогою Java

Почнемо з простого прикладу розрахунку розміру папки - з використанням суми її вмісту :

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() { @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 , застосовуючи функцію length у кожному елементі - після чого ми можемо підсумувати та отримати кінцевий результат.

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. З гуавою

А тепер - давайте подивимося, як розрахувати розмір папки за допомогою гуави . У наступному прикладі - ми використовуємо Files.fileTreeTraverser () для обходу всіх файлів у папці для підсумовування їх розміру:

@Test public void whenGetFolderSizeUsingGuava_thenCorrect() { long expectedSize = 12607; File folder = new File("src/test/resources"); Iterable 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, тому його слід легко імпортувати та запускати як є.