Java MappedByteBuffer gebruiken

1. Overzicht

In dit korte artikel zullen we kijken naar de MappedByteBuffer in de java.nio pakket. Dit hulpprogramma kan erg handig zijn voor het efficiënt lezen van bestanden.

2. Hoe MappedByteBuffer Works

Wanneer we een regio van het bestand laden, kunnen we deze in de specifieke geheugenregio laden die later toegankelijk is.

Als we weten dat we de inhoud van een bestand meerdere keren moeten lezen, is het een goed idee om het kostbare proces te optimaliseren, bijvoorbeeld door die inhoud in het geheugen op te slaan. Dankzij dat zullen daaropvolgende zoekopdrachten van dat deel van het bestand alleen naar het hoofdgeheugen gaan zonder dat de gegevens van de schijf hoeven te worden geladen, waardoor de latentie aanzienlijk wordt verminderd.

Een ding waar we voorzichtig mee moeten zijn bij het gebruik van de MappedByteBuffer is wanneer we werken met zeer grote bestanden van schijf - we moeten ervoor zorgen dat het bestand in het geheugen past.

Anders kunnen we het hele geheugen opvullen en als gevolg daarvan tegen het gemeenschappelijke aanlopen OutOfMemoryException. We kunnen dat verhelpen door slechts een deel van het bestand te laden - bijvoorbeeld op basis van gebruikspatronen.

3. Het bestand lezen met MappedByteBuffer

Laten we zeggen dat we een bestand hebben met de naam fileToRead.txt met de volgende inhoud:

Dit is een inhoud van het bestand

Het bestand bevindt zich in het / resource directory zodat we het kunnen laden met behulp van de volgende functie:

Pad getFileURIFromResources (String bestandsnaam) genereert Uitzondering {ClassLoader classLoader = getClass (). GetClassLoader (); return Paths.get (classLoader.getResource (bestandsnaam) .getPath ()); }

Om het MappedByteBuffer vanuit een bestand, moeten we eerst een FileChannel van het. Zodra we ons kanaal hebben gemaakt, kunnen we het kaart() methode op het passeren in de MapMode, een positie waaruit we willen lezen, en de grootte parameter die specificeert hoeveel bytes we willen:

CharBuffer charBuffer = null; Pad pathToRead = getFileURIFromResources ("fileToRead.txt"); probeer (FileChannel fileChannel (FileChannel) Files.newByteChannel (pathToRead, EnumSet.of (StandardOpenOption.READ)))) {MappedByteBuffer mappedByteBuffer = fileChannel .map (FileChannel.MapMode.READ_ONLY, 0s, file (Channel ). if (mappedByteBuffer! = null) {charBuffer = Charset.forName ("UTF-8"). decode (mappedByteBuffer); }}

Nadat we ons bestand in de geheugen toegewezen buffer hebben toegewezen, kunnen we de gegevens ervan in het CharBuffer. Belangrijk om op te merken is dat hoewel we de inhoud van het bestand lezen, we de decoderen() methode passeren MappedByteBuffer, we lezen uit het geheugen, niet van de schijf. Daarom zal dat lezen erg snel zijn.

We kunnen beweren dat de inhoud die we uit ons bestand lezen, de daadwerkelijke inhoud is van het fileToRead.txt het dossier:

assertNotNull (charBuffer); assertEquals (charBuffer.toString (), "Dit is de inhoud van het bestand");

Elke volgende lezing van de mappedByteBuffer zal erg snel zijn omdat de inhoud van het bestand in het geheugen wordt afgebeeld en het lezen gebeurt zonder dat gegevens van de schijf hoeven te worden opgezocht.

4. Schrijven naar het bestand met MappedByteBuffer

Laten we zeggen dat we wat inhoud in het bestand willen schrijven fileToWriteTo.txt de ... gebruiken MappedByteBuffer API. Om dat te bereiken, moeten we het FileChannel en bel de kaart() methode erop, het doorgeven van de FileChannel.MapMode.READ_WRITE.

Vervolgens kunnen we de inhoud van het CharBuffer in het bestand met behulp van de leggen() methode van de MappedByteBuffer:

CharBuffer charBuffer = CharBuffer .wrap ("Dit wordt naar het bestand geschreven"); Pad pathToWrite = getFileURIFromResources ("fileToWriteTo.txt"); probeer (FileChannel fileChannel = (FileChannel) Files .newByteChannel (pathToWrite, EnumSet.of (StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING))) {MappedByteBuffer mappedByteBuffer. lengte()); if (mappedByteBuffer! = null) {mappedByteBuffer.put (Charset.forName ("utf-8"). encode (charBuffer)); }}

We kunnen stellen dat de feitelijke inhoud van de charBuffer is naar het bestand geschreven door de inhoud ervan te lezen:

Lijst fileContent = Files.readAllLines (pathToWrite); assertEquals (fileContent.get (0), "Dit wordt naar het bestand geschreven");

5. Conclusie

In deze korte tutorial keken we naar de MappedByteBuffer construeren vanuit de java.nio pakket.

Dit is een zeer efficiënte manier om de inhoud van het bestand meerdere keren te lezen, aangezien het bestand in het geheugen wordt gemapt en de daaropvolgende leesbewerkingen niet elke keer naar schijf hoeven te gaan.

Al deze voorbeelden en codefragmenten zijn te vinden op GitHub - dit is een Maven-project, dus het zou gemakkelijk te importeren en uit te voeren moeten zijn zoals het is.