Java NIO File Read Write with Channels

Last modified on September 13th, 2015 by Joe.

In this Java tutorial, we will see about how to read and write files using NIO channels. Channels are used for data transfer between a buffer and an entity. There are different channels like ByteChannel, FileChannel, SocketChannel and DatagramChannel. In this tutorial we will learn about using ByteChannel and FileChannel to perform file IO operations. Just wanted to remind you, I am publishing a Java NIO tutorial series and this tutorial is part of it. Go through the NIO Channel tutorial to know more about NIO channels.

Before going into using NIO channels to read and write files, let us do a quick recap of our standard file I/O operations. Hope you remember the buffered readers and IO streams which we have been using long to do IO operations in Java.

Buffered File Read Write

We create an instance of BufferedReader and read line by line till end of file.

Read File

	Charset charset = Charset.forName("US-ASCII");
	Path filePath = FileSystems.getDefault().getPath(".", "temp.txt");

	BufferedReader bufferedReader = Files.newBufferedReader(filePath,
			charset);
	String line = null;
	while ((line = bufferedReader.readLine()) != null) {
		System.out.println(line);
	}

Write File

	Charset charset = Charset.forName("US-ASCII");
	Path filePath = FileSystems.getDefault().getPath(".", "tempCopy1.txt");

	BufferedWriter bufferedWriter = Files.newBufferedWriter(filePath,
			charset);

	System.out.println(string);
	bufferedWriter.write(string, 0, string.length());

Stream File Read Write

Read File

	Path filePath = FileSystems.getDefault().getPath(".", "temp.txt");
	InputStream inputStream = Files.newInputStream(filePath);
	BufferedReader bufferedReader = new BufferedReader(
			new InputStreamReader(inputStream));
	String line = null;
	while ((line = bufferedReader.readLine()) != null) {
		System.out.println(line);
	}

Write File

	Path filePath = FileSystems.getDefault().getPath(".", "tempCopy2.txt");
	OutputStream outputStream = new BufferedOutputStream(
			Files.newOutputStream(filePath, StandardOpenOption.CREATE,
					StandardOpenOption.APPEND));
	outputStream.write(byteArray, 0, byteArray.length);

Simple NIO File Read Write

Before going into NIO channels lets see a simplistic NIO way to read write files. If you got a small file and just want to read it in one go, then use the readAllBytes from NIO Files API and similarly for write operation too.

	// create a path for file named temp.txt from current folder
	Path filePath = FileSystems.getDefault().getPath(".", "temp.txt");

	// read a complete file in one go as byte array
	// use this to read small files
	byte[] byteArray = Files.readAllBytes(filePath);

	Path fileCopy = FileSystems.getDefault().getPath(".", "tempCopy.txt");
	Files.write(fileCopy, byteArray);

File Read with ByteChannel

We create an instance for byte channel using Files NIO utility class. Then we allocate a ByteBuffer using which the data will be read. rewind is used to read again the data it already contains. rewind sets the buffer position to zero. flip is used to prepare a buffer for get operation and makes it ready.

public static void byteChannelRead() throws IOException {
	Path filePath = FileSystems.getDefault().getPath(".", "temp.txt");
	SeekableByteChannel byteChannel = Files.newByteChannel(filePath);
	ByteBuffer byteBuffer = ByteBuffer.allocate(10);

	Charset charset = Charset.forName("US-ASCII");
	while (byteChannel.read(byteBuffer) > 0) {
		byteBuffer.rewind();
		System.out.print(charset.decode(byteBuffer));
		byteBuffer.flip();
	}
}

File Write with ByteChannel

We set the options mode like create/append using StandardOpenOption and then write the buffer using the channel.

	public static void byteChannelWrite(ByteBuffer byteBuffer)
			throws IOException {

		Set options = new HashSet();
		options.add(StandardOpenOption.CREATE);
		options.add(StandardOpenOption.APPEND);

		Path file = Paths.get("./byByteChannel.txt");

		SeekableByteChannel byteChannel = Files.newByteChannel(file, options);
		byteChannel.write(byteBuffer);
	}

File Read with FileChannel

ByteChannel and FileChannel usage are almost similar, the way we create the instances are little bit different.

	public static void fileChannelRead() throws IOException {
		RandomAccessFile randomAccessFile = new RandomAccessFile("./temp.txt",
				"rw");
		FileChannel fileChannel = randomAccessFile.getChannel();
		ByteBuffer byteBuffer = ByteBuffer.allocate(512);
		Charset charset = Charset.forName("US-ASCII");
		while (fileChannel.read(byteBuffer) > 0) {
			byteBuffer.rewind();
			System.out.print(charset.decode(byteBuffer));
			byteBuffer.flip();
		}
		fileChannel.close();
		randomAccessFile.close();
	}

File Write with FileChannel

	public static void fileChannelWrite(ByteBuffer byteBuffer)
			throws IOException {

		Set options = new HashSet();
		options.add(StandardOpenOption.CREATE);
		options.add(StandardOpenOption.APPEND);

		Path path = Paths.get("./byFileChannel.txt");

		FileChannel fileChannel = FileChannel.open(path, options);
		fileChannel.write(byteBuffer);
		fileChannel.close();
	}

Example Channel File I/O Full Code

	
package com.javapapers.java.nio;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.HashSet;
import java.util.Set;

public class JavaNIOReadWriteChannels {

	public static void main(String args[]) throws IOException {
		byteChannelRead();

		String string = "foo bar";
		byte[] byteArray = string.getBytes();
		ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
		byteChannelWrite(byteBuffer);
		
		fileChannelRead();
		fileChannelWrite(byteBuffer);

	}

	public static void byteChannelRead() throws IOException {

		Path filePath = FileSystems.getDefault().getPath(".", "temp.txt");

		SeekableByteChannel byteChannel = Files.newByteChannel(filePath);
		ByteBuffer byteBuffer = ByteBuffer.allocate(10);

		Charset charset = Charset.forName("US-ASCII");
		while (byteChannel.read(byteBuffer) > 0) {
			byteBuffer.rewind();
			System.out.print(charset.decode(byteBuffer));
			byteBuffer.flip();
		}
	}

	public static void byteChannelWrite(ByteBuffer byteBuffer)
			throws IOException {

		Set options = new HashSet();
		options.add(StandardOpenOption.CREATE);
		options.add(StandardOpenOption.APPEND);

		Path file = Paths.get("./byByteChannel.txt");

		SeekableByteChannel byteChannel = Files.newByteChannel(file, options);
		byteChannel.write(byteBuffer);
	}

	public static void fileChannelRead() throws IOException {
		RandomAccessFile randomAccessFile = new RandomAccessFile("./temp.txt",
				"rw");
		FileChannel fileChannel = randomAccessFile.getChannel();
		ByteBuffer byteBuffer = ByteBuffer.allocate(512);
		Charset charset = Charset.forName("US-ASCII");
		while (fileChannel.read(byteBuffer) > 0) {
			byteBuffer.rewind();
			System.out.print(charset.decode(byteBuffer));
			byteBuffer.flip();
		}
		fileChannel.close();
		randomAccessFile.close();
	}

	public static void fileChannelWrite(ByteBuffer byteBuffer)
			throws IOException {

		Set options = new HashSet();
		options.add(StandardOpenOption.CREATE);
		options.add(StandardOpenOption.APPEND);

		Path path = Paths.get("./byFileChannel.txt");

		FileChannel fileChannel = FileChannel.open(path, options);
		fileChannel.write(byteBuffer);
		fileChannel.close();
	}

}