Java - Directory-grootte

1. Overzicht

In deze zelfstudie leren we hoe u het grootte van een map in Java - gebruik van Java 6, 7 en de nieuwe Java 8, evenals Guava en Apache Common IO.

Ten slotte krijgen we ook een voor mensen leesbare weergave van de directorygrootte.

2. Met Java

Laten we beginnen met een eenvoudig voorbeeld van het berekenen van de grootte van een map - gebruikmakend van de som van de inhoud:

privé lang getFolderSize (bestandsmap) {lange lengte = 0; Bestand [] bestanden = folder.listFiles (); int count = files.length; voor (int i = 0; i <count; i ++) {if (bestanden [i] .isFile ()) {lengte + = bestanden [i] .length (); } anders {lengte + = getFolderSize (bestanden [i]); }} retour lengte; }

We kunnen onze methode testen getFolderSize () zoals in het volgende voorbeeld:

@Test openbare leegte whenGetFolderSizeRecursive_thenCorrect () {lang verwachteSize = 12607; Bestandsmap = nieuw bestand ("src / test / resources"); lange grootte = getFolderSize (map); assertEquals (verwachte grootte, grootte); }

Opmerking: lijstFiles () wordt gebruikt om de inhoud van de gegeven map weer te geven.

3. Met Java 7

Volgende - laten we eens kijken hoe we het kunnen gebruiken Java 7 om de mapgrootte te krijgen. In het volgende voorbeeld gebruiken we Files.walkFileTree () om alle bestanden in de map te doorlopen om hun grootte bij elkaar op te tellen:

@Test openbare leegte whenGetFolderSizeUsingJava7_thenCorrect () gooit IOException {lang verwachteSize = 12607; AtomicLong size = nieuwe AtomicLong (0); Padmap = Paths.get ("src / test / resources"); Files.walkFileTree (map, nieuwe SimpleFileVisitor () {@Override openbare FileVisitResult visitFile (padbestand, BasicFileAttributes attrs) gooit IOException {size.addAndGet (attrs.size ()); retourneer FileVisitResult.CONTINUE;}}); assertEquals (verwachteSize, size.longValue ()); }

Merk op hoe we hier de mogelijkheden voor het doorlopen van de boomstructuur van het bestandssysteem benutten en het bezoekerspatroon gebruiken om ons te helpen bij het bezoeken en berekenen van de grootte van elk bestand en elke submap.

4. Met Java 8

Laten we nu eens kijken hoe we de mapgrootte kunnen krijgen met Java 8, streambewerkingen en lambda's. In het volgende voorbeeld gebruiken we Files.walk () om alle bestanden in de map te doorlopen om hun grootte bij te tellen:

@Test openbare leegte whenGetFolderSizeUsingJava8_thenCorrect () gooit IOException {lang verwachteSize = 12607; Padmap = Paths.get ("src / test / resources"); long size = Files.walk (map) .filter (p -> p.toFile (). isFile ()) .mapToLong (p -> p.toFile (). length ()) .sum (); assertEquals (verwachte grootte, grootte); }

Opmerking: mapToLong () wordt gebruikt om een LongStream door de lengte functie in elk element - waarna we kunnen som en krijg een eindresultaat.

5. Met Apache Commons IO

Vervolgens - laten we eens kijken hoe we de mapgrootte kunnen krijgen met Apache Commons IO. In het volgende voorbeeld gebruiken we gewoon FileUtils.sizeOfDirectory () om de mapgrootte te krijgen:

@Test openbare leegte whenGetFolderSizeUsingApacheCommonsIO_thenCorrect () {lang verwachteSize = 12607; Bestandsmap = nieuw bestand ("src / test / resources"); lange grootte = FileUtils.sizeOfDirectory (map); assertEquals (verwachte grootte, grootte); }

Merk op dat deze to the point utility-methode een eenvoudige Java 6-oplossing onder de motorkap implementeert.

Merk ook op dat de bibliotheek ook een FileUtils.sizeOfDirectoryAsBigInteger () methode die beter omgaat met beveiligde mappen.

6. Met Guava

Laten we nu eens kijken hoe we de grootte van een map kunnen berekenen met Guave. In het volgende voorbeeld gebruiken we Files.fileTreeTraverser () om alle bestanden in de map te doorlopen om hun grootte bij te tellen:

@ Test openbare leegte whenGetFolderSizeUsingGuava_thenCorrect () {lang verwachteSize = 12607; Bestandsmap = nieuw bestand ("src / test / resources"); Herhaalde bestanden = Files.fileTraverser (). BreadthFirst (map); lange grootte = StreamSupport.stream (files.spliterator (), false) .filter (f -> f.isFile ()) .mapToLong (File :: length) .sum (); assertEquals (verwachte grootte, grootte); }

7. Door mensen leesbare grootte

Laten we tot slot kijken hoe we een beter leesbare weergave van de mapgrootte kunnen krijgen, niet alleen een grootte in bytes:

@Test public void whenGetReadableSize_thenCorrect () {Bestandsmap = nieuw bestand ("src / test / resources"); lange grootte = getFolderSize (map); String [] units = nieuwe String [] {"B", "KB", "MB", "GB", "TB"}; int unitIndex = (int) (Math.log10 (grootte) / 3); dubbele unitValue = 1 << (unitIndex * 10); String readableSize = nieuwe DecimalFormat ("#, ## 0. #") .format (size / unitValue) + "" + units [unitIndex]; assertEquals ("12.3 KB", readableSize); }

Opmerking: we gebruikten DecimalFormat ("#, ## 0, #") om het resultaat af te ronden tot één cijfer achter de komma.

8. Opmerkingen

Hier zijn enkele opmerkingen over het berekenen van de mapgrootte:

  • Beide Files.walk () en Files.walkFileTree () zal een SecurityException genereren als de beveiligingsmanager de toegang tot het startbestand weigert.
  • De oneindige lus kan optreden als de map symbolische koppelingen bevat.

9. Conclusie

In deze korte tutorial hebben we voorbeelden geïllustreerd van het gebruik van different Java versies, Apache Commons IO en Guave om de grootte van een map in het bestandssysteem te berekenen.

De implementatie van deze voorbeelden is te vinden in het GitHub-project - dit is een op Maven gebaseerd project, dus het moet gemakkelijk te importeren en uit te voeren zijn zoals het is.