MappedByteBuffer

Java MappedByteBuffer Example

In this post, we are going to discuss about the class java.nio.MappedByteBuffer
 
 
 
 
 
 
 
 
 

1. MappedByteBuffer Class

There are two ways for reading a file, sequentially and randomly. Files that can be explored sequentially are known as sequential files. Files that permit random access to their contents are known as random access files (RAFs). Sequential files are used more often because they are easy to create, but RAFs are more flexible and their data can be located faster.

With a RAF, you can open the file, seek a particular location, and read from or write to that file. After you open a RAF, you can read from it or write to it in a random manner just by using a record number, or you can add to the beginning or end of the file since you know how many records are in the file. A RAF allows you to read a single character, read a chunk of bytes or a line, replace a portion of the file, append lines, delete lines, and so forth, and allows you to perform all of these actions in a random manner.

FileChannel was introduced in Java 4, but recently it was updated to implement the new SeekableByteChannel interface, combining their forces to achieve more power. SeekableByteChannel provides the random access file feature, while FileChannel offers great advanced features such as mapping a region of the file directly into memory for faster access and locking a region of the file.

One of the great FileChannel facilities is the capability to map a region of a channel’s file directly into memory. This is possible thanks to the FileChannel.map() method. The map() method will return a MappedByteBuffer that actually represents the extracted region.

Before going deeper into the MappedByteBuffer class, let’s talk about a little some important topics when working with random access files (RAFs).

1.1 What is a buffer?

A buffer is essentially an array (usually of bytes) that holds some data to be written or that was just read (Java has the ByteBuffer class).

Three are the essential properties of a buffer:

  • Limit – When writing from a buffer, the limit specifies how much data remains to get.
  • Position – The position keeps track of how much data you have read or written.
  • Capacity – The capacity specifies the maximum amount of data that can be stored in a buffer.

1.2 What is a channel?

In a stream-oriented I/O system, an input stream produces 1 byte of data and an output stream consumes 1 byte of data. By contrast, in a block-oriented I/O system, the input/output stream produces or consumes a block of data in one step.

Channels are analogous to streams, but with a few differences:

  • While streams are typically one-way (read or write), channels support read and write.
  • Channels can be read and written asynchronously.
  • Channels always read to, or write from, a buffer. All data that is sent to a channel must first be placed in a buffer. Any data that is read from a channel is read into a buffer.

The new SeekableByteChannel interface provides support for RAF by implementing the notion of position over channels. We can read or write a ByteBuffer from or to a channel, get or set the current position, and truncate an entity connected to a channel to a specified dimension.

Let’s see an example of using the MappedByteBuffer Class file.

2. Executing some code

App.java

package com.javacodegeeks.examples.mappedbytebuffer;

import java.io.File;
import java.io.IOException;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.EnumSet;
import java.util.logging.Level;
import java.util.logging.Logger;

public class App {
	private static final Logger logger = Logger.getLogger("App");

	private static final String FILE_READ = "rafRead.txt";
	//= Change this according to your needs =========================
	private static final String FILE_WRITE = "C:\\Tmp\\rafWrite.txt";

	// ========================================================================
	// = Utility function to get a file located in the classpath ==============
	// ========================================================================
	public static Path getFileURIFromClasspath(String fileName) throws Exception {
		Path result = null;

		String classpath = System.getProperty("java.class.path");
		result = FileSystems.getDefault().getPath(classpath + File.separator + fileName);
		
		return result;
	}

	public static void main(String[] args) {
		CharBuffer charBuffer = null;
		String charEncoding = null;
		MappedByteBuffer mappedByteBuffer = null;
		
		try {
			charEncoding = System.getProperty("file.encoding");
			
			// Read a file
			Path pathRead = App.getFileURIFromClasspath(App.FILE_READ);
			if (Files.exists(pathRead, new LinkOption[]{LinkOption.NOFOLLOW_LINKS})) {
				try (FileChannel fileChannel = (FileChannel) Files.newByteChannel(pathRead, EnumSet.of(StandardOpenOption.READ))) {
					mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());

					if (mappedByteBuffer != null) {
						logger.info("Reading file...");
						charBuffer = Charset.forName(charEncoding).decode(mappedByteBuffer);
						logger.info("File content: " + charBuffer.toString());
					}
				} catch (IOException ioe) {
					logger.log(Level.SEVERE, ioe.getMessage());
					ioe.printStackTrace();
				}
			}
			
			// Write a file
			Path pathWrite = FileSystems.getDefault().getPath(App.FILE_WRITE);
			if (Files.notExists(pathWrite, new LinkOption[]{LinkOption.NOFOLLOW_LINKS})) {
				Files.createFile(pathWrite);
				
				try (FileChannel fileChannel = (FileChannel) Files.newByteChannel(pathWrite, EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING))) {
					mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, charBuffer.length());
					
					if (mappedByteBuffer != null) {
						logger.info("Writing to file...");
						mappedByteBuffer.put(Charset.forName(charEncoding).encode(charBuffer));
						logger.info("Done!");
					}
				} catch (IOException ioe) {
					logger.log(Level.SEVERE, ioe.getMessage());
					ioe.printStackTrace();
				}
			}
			
		} catch (Exception e) {
			logger.log(Level.SEVERE, e.getMessage());
			e.printStackTrace(System.err);
		}
	}
}

Let’s explain the methods used in the previous code

The output of the command

com.javacodegeeks.examples.mappedbytebuffer.App

should be similar to:

Sep 30, 2014 1:26:08 PM com.javacodegeeks.examples.mappedbytebuffer.App main
INFO: Reading file...
Sep 30, 2014 1:26:08 PM com.javacodegeeks.examples.mappedbytebuffer.App main
INFO: File content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas et ligula metus.
Quisque ullamcorper, nisi sit amet hendrerit iaculis, lacus nibh sodales ante, tincidunt facilisis elit ligula quis risus.
Donec sed enim placerat, interdum elit ut, rhoncus erat.
Vestibulum id lobortis enim. Morbi dolor metus, auctor sollicitudin diam nec, mollis venenatis nibh.
Pellentesque habitant morbi tristique senectus et netus et malesuadafames ac turpis egestas.
Duis commodo massa sed quam maximus blandit.
Sep 30, 2014 1:26:08 PM com.javacodegeeks.examples.mappedbytebuffer.App main
INFO: Writing to file...
Sep 30, 2014 1:26:08 PM com.javacodegeeks.examples.mappedbytebuffer.App main
INFO: Done!

3. Download the Eclipse project of this tutorial:

This was an example of how to set use the MappedByteBuffer Class.

Download
You can download the full source code of this example here : mappedbytebuffer.zip

Armando Flores

Armando graduated from from Electronics Engineer in the The Public University Of Puebla (BUAP). He also has a Masters degree in Computer Sciences from CINVESTAV. He has been using the Java language for Web Development for over a decade. He has been involved in a large number of projects focused on "ad-hoc" Web Application based on Java EE and Spring Framework.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button