Brug af Java MappedByteBuffer

1. Oversigt

I denne hurtige artikel ser vi på MappedByteBuffer i java.nio pakke. Dette værktøj kan være ret nyttigt til effektiv fillæsning.

2. Hvordan MappedByteBuffer Works

Når vi indlæser en region i filen, kan vi indlæse den til den bestemte hukommelsesregion, der kan tilgås senere.

Når vi ved, at vi bliver nødt til at læse indholdet af en fil flere gange, er det en god ide at optimere den dyre proces, f.eks. ved at gemme dette indhold i hukommelsen. Takket være det vil efterfølgende opslag af den del af filen kun gå til hovedhukommelsen uden behov for at indlæse data fra disken, hvilket reducerer ventetiden betydeligt.

En ting, som vi skal være forsigtige med, når vi bruger MappedByteBuffer er når vi arbejder med meget store filer fra disk - vi er nødt til at sikre, at filen passer i hukommelsen.

Ellers kan vi fylde hele hukommelsen og følgelig løbe ind i det fælles OutOfMemoryException. Vi kan overvinde det ved kun at indlæse en del af filen - for eksempel baseret på brugsmønstre.

3. Læsning af filen ved hjælp af MappedByteBuffer

Lad os sige, at vi har en fil, der hedder fileToRead.txt med følgende indhold:

Dette er et indhold i filen

Filen findes i / ressource katalog, så vi kan indlæse den ved hjælp af følgende funktion:

Stien getFileURIFromResources (streng filnavn) kaster undtagelse {ClassLoader classLoader = getClass (). GetClassLoader (); returner Paths.get (classLoader.getResource (filnavn) .getPath ()); }

At oprette MappedByteBuffer Fra en fil skal vi først oprette en FileChannel fra det. Når vi først har oprettet vores kanal, kan vi påberåbe os kort() metode på det passerer i MapMode, -en position hvorfra vi vil læse, og størrelse parameter, der angiver, hvor mange byte vi vil have:

CharBuffer charBuffer = null; Sti pathToRead = getFileURIFromResources ("fileToRead.txt"); prøv (FileChannel fileChannel (FileChannel) Files.newByteChannel (pathToRead, EnumSet.of (StandardOpenOption.READ))) {MappedByteBuffer mappedByteBuffer = fileChannel .map (FileChannel.MapMode.READ_ONLY, 0, fileChannel.size); hvis (mappedByteBuffer! = null) {charBuffer = Charset.forName ("UTF-8"). afkode (mappedByteBuffer); }}

Når vi først har kortlagt vores fil i den hukommelseskortede buffer, kan vi læse dataene fra den i CharBuffer. Vigtigt at bemærke er, at selvom vi læser indholdet af filen, når vi ringer til afkode () metode passerer MappedByteBuffer, vi læser fra hukommelsen, ikke fra disken. Derfor vil denne læsning være meget hurtig.

Vi kan hævde, at det indhold, vi læser fra vores fil, er det faktiske indhold af fileToRead.txt fil:

assertNotNull (charBuffer); assertEquals (charBuffer.toString (), "Dette er et indhold i filen");

Hver efterfølgende læsning fra mappedByteBuffer vil være meget hurtig, fordi indholdet af filen kortlægges i hukommelsen, og læsning sker uden behov for at slå op data fra disken.

4. Skrivning til filen ved hjælp af MappedByteBuffer

Lad os sige, at vi vil skrive noget indhold i filen fileToWriteTo.txt bruger MappedByteBuffer API. For at opnå det er vi nødt til at åbne FileChannel og ring til kort() metode på det, passerer i FileChannel.MapMode.READ_WRITE.

Dernæst kan vi gemme indholdet af CharBuffer ind i filen ved hjælp af sætte() metode fra MappedByteBuffer:

CharBuffer charBuffer = CharBuffer. Wrap ("Dette vil blive skrevet til filen"); Sti pathToWrite = getFileURIFromResources ("fileToWriteTo.txt"); prøv (FileChannel fileChannel = (FileChannel) Files .newByteChannel (pathToWrite, EnumSet.of (StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING))) {MappedByteBuffer mappedByteBufferapad. FileChannel. FileChannel. længde ()); hvis (mappedByteBuffer! = null) {mappedByteBuffer.put (Charset.forName ("utf-8"). kode (charBuffer)); }}

Vi kan hævde, at det faktiske indhold af charBuffer blev skrevet til filen ved at læse indholdet af den:

Liste fileContent = Files.readAllLines (pathToWrite); assertEquals (fileContent.get (0), "Dette vil blive skrevet til filen");

5. Konklusion

I denne hurtige vejledning så vi på MappedByteBuffer konstruere fra java.nio pakke.

Dette er en meget effektiv måde at læse indholdet af filen flere gange på, da filen kortlægges i hukommelsen, og efterfølgende læsninger ikke behøver at gå til disk hver gang.

Alle disse eksempler og kodestykker kan findes på GitHub - dette er et Maven-projekt, så det skal være let at importere og køre som det er.