Java - Dimensione della directory

1. Panoramica

In questo tutorial impareremo come ottenere la dimensione di una cartella in Java , utilizzando Java 6, 7 e il nuovo Java 8, Guava e Apache Common IO.

Infine, otterremo anche una rappresentazione leggibile dall'uomo della dimensione della directory.

2. Con Java

Cominciamo con un semplice esempio di calcolo delle dimensioni di una cartella, utilizzando la somma del suo contenuto :

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; }

Possiamo testare il nostro metodo getFolderSize () come nel seguente esempio:

@Test public void whenGetFolderSizeRecursive_thenCorrect() { long expectedSize = 12607; File folder = new File("src/test/resources"); long size = getFolderSize(folder); assertEquals(expectedSize, size); }

Nota: listFiles () viene utilizzato per elencare il contenuto di una determinata cartella.

3. Con Java 7

Successivamente, vediamo come utilizzare Java 7 per ottenere la dimensione della cartella . Nel seguente esempio, usiamo Files.walkFileTree () per attraversare tutti i file nella cartella per sommarne le dimensioni:

@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()); }

Nota come stiamo sfruttando le capacità di attraversamento dell'albero del filesystem qui e facendo uso del pattern del visitatore per aiutarci a visitare e calcolare le dimensioni di ogni file e sottocartella.

4. Con Java 8

Vediamo ora come ottenere la dimensione della cartella utilizzando Java 8, operazioni di flusso e lambda . Nel seguente esempio, utilizziamo Files.walk () per attraversare tutti i file nella cartella per sommarne le dimensioni:

@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); }

Nota: mapToLong () viene utilizzato per generare un LongStream applicando la funzione di lunghezza in ogni elemento, dopodiché possiamo sommare e ottenere un risultato finale.

5. Con Apache Commons IO

Successivamente, vediamo come ottenere la dimensione della cartella utilizzando Apache Commons IO . Nel seguente esempio, usiamo semplicemente FileUtils.sizeOfDirectory () per ottenere la dimensione della cartella:

@Test public void whenGetFolderSizeUsingApacheCommonsIO_thenCorrect() { long expectedSize = 12607; File folder = new File("src/test/resources"); long size = FileUtils.sizeOfDirectory(folder); assertEquals(expectedSize, size); }

Si noti che questo metodo di utilità del punto implementa una semplice soluzione Java 6 sotto il cofano.

Inoltre, si noti che la libreria fornisce anche un metodo FileUtils.sizeOfDirectoryAsBigInteger () che gestisce meglio le directory con limitazioni di sicurezza.

6. Con Guava

Ora vediamo come calcolare la dimensione di una cartella usando Guava . Nel seguente esempio, usiamo Files.fileTreeTraverser () per attraversare tutti i file nella cartella per sommarne le dimensioni:

@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. Dimensione leggibile dall'uomo

Infine, vediamo come ottenere una rappresentazione più leggibile dall'utente della dimensione della cartella, non solo una dimensione in byte:

@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); }

Nota: abbiamo utilizzato DecimalFormat ("#, ## 0, #") per arrotondare il risultato a una cifra decimale.

8. Note

Ecco alcune note sul calcolo delle dimensioni della cartella:

  • Sia Files.walk () che Files.walkFileTree () genereranno un'eccezione SecurityException se il gestore della sicurezza nega l'accesso al file iniziale.
  • Il ciclo infinito può verificarsi se la cartella contiene collegamenti simbolici.

9. Conclusione

In questo breve tutorial, abbiamo illustrato esempi di utilizzo di diverse versioni di Java , Apache Commons IO e Guava per calcolare la dimensione di una directory nel file system.

L'implementazione di questi esempi può essere trovata nel progetto GitHub: questo è un progetto basato su Maven, quindi dovrebbe essere facile da importare ed eseguire così com'è.