java.nio.channels.FileChannel Example

This article introduces the FileChannel class and its basic usage. This class is available since Java 1.4 as part of Java NIO (New IO) File API. This article shows reading from and writing to file using file channels.

The examples in this article are compiled and run in Windows OS environment. Note that Java SE 7 is required to run the code.
 
 
 
 
 
 

Want to be a Java NIO Master ?
Subscribe to our newsletter and download the JDBC Ultimate Guide right now!
In order to help you master Java NIO Library, we have compiled a kick-ass guide with all the major Java NIO features and use cases! Besides studying them online you may download the eBook in PDF format!

Thank you!

We will contact you soon.

1. Introduction

NIO allows Java programmers to implement high-speed I/O without having to write custom native code. NIO moves the most time consuming I/O activities (like, filling and draining buffers) back into the operating system, thus providing increase in speed. NIO makes I/O faster than traditional I/O.

Java NIO library implements the NIO APIs. Java NIO is not a substitute to Java IO, rather is a complement to it. Since Java 1.4, there have been enhancements in NIO (and IO) in Java SE 5, 6 and 7 versions.

Buffers and channels are the main concepts of the NIO.

2. Buffers and Channels

Buffers provide a mechanism to store a fixed amount of primitive data elements in an in-memory container. In the NIO, all data is handled with buffers. When data is read, it is read directly into a buffer. When data is written, it is written into a buffer.

Buffers work with channels. Channels are portals through which I/O transfers take place, and buffers are the sources or targets of those data transfers.

The examples in this article use ByteBuffer and FileChannel classes. ByteBuffer is defined in the java.nio package and FileChannel in the java.nio.channels package. To read a file and move data to a target – the file is read into a buffer through a channel and then the data is moved from the buffer to the target. To write to a file from a source – the source data is moved into a buffer and then written to the file through a channel.

3. Reading and Writing Files using FileChannel

File channels are read/write channels and they are always blocking. This is a channel for reading, writing, mapping, and manipulating a file. FileChannel objects are thread-safe.

A FileChannel instance can be obtained by calling getChannel() method on an open file object (RandomAccessFile, FileInputStream, or FileOutputStream), -or- from the FileChannel‘s open() static method to which a file Path is supplied. The methods return a FileChannel object connected to the underlying file. In this article, both ways of creating a channel is shown.

The following sections explain two examples using file channel to: read a file and write to a file.

4. Reading from a File

This example shows the steps to read a file using a file channel into a buffer and print the buffer contents.

4.1. Input file:

This is an existing text file with contents: 1234567890

4.2. Create a channel:

The file channel’s open() static method is used to create a channel. The method opens a file, returning a FileChannel to access the supplied file.

Path path = Paths.get("readfile.txt");
FileChannel fileChannel = FileChannel.open(path);

4.3. Create a buffer:

Create a ByteBuffer using the ByteBuffer‘s allocate() static method. The new buffer’s position will be zero, its limit will be its capacity and its elements will be initialized to zero. In this example, the initial capacity is set to 6.

ByteBuffer buffer = ByteBuffer.allocate(6);

4.4. Read from the channel into the buffer:

FileChannel‘s read() method reads a sequence of bytes into the given buffer. The method returns the number of bytes read, or -1 if the channel has reached the end-of-stream.

int noOfBytesRead = fileChannel.read(buffer);

Bytes are read starting at the channel’s current file position (initially zero), and then the file position is updated with the number of bytes actually read (in the example, the position will be 6 after initial read). The channel’s position() method returns the current position.

The ByteBuffer also has a position() method. Initially this is zero. After the first read, the value is 6. The buffer’s flip() method makes a buffer ready for a new sequence of relative get operations: It sets the limit to the current position (in this example, 6) and then sets the position to zero.

buffer.flip();

4.5. Print the buffer contents:

while (buffer.hasRemaining()) {
    System.out.print((char) buffer.get());
}

The buffer’s clear() method makes a buffer ready for a new sequence of channel-read: It sets the limit to the capacity (6) and the position to zero.

buffer.clear();

4.6. Close:

File channel’s close() method closes this channel.

Exceptions: In the example, FileChannel‘s open(), close(), position() and read() methods throw IOException.

The following is the complete code for the example showing the reading from a file using file channel.

FileChannelRead.java

import java.io.file.Paths;
import java.nio.file.Path;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.io.FileReader;
import java.io.BufferedReader;
public class FileChannelRead {
    public static void main (String [] args)
            throws Exception {
        new FileChannelRead().readFile();
    }
    private void readFile()
            throws IOException {
        String filePath = "readfile.txt";
        printFileContents(filePath);
        Path path = Paths.get(filePath);
        FileChannel fileChannel =  FileChannel.open(path);
        ByteBuffer buffer = ByteBuffer.allocate(6);
        int noOfBytesRead = fileChannel.read(buffer);
		
        while (noOfBytesRead != -1) {
            System.out.println("Number of bytes read: " + noOfBytesRead);
            buffer.flip();
            System.out.print("Buffer contents: ");
            while (buffer.hasRemaining()) {
                System.out.print((char) buffer.get());                    
            }
            System.out.println(" ");
            buffer.clear();
            noOfBytesRead = fileChannel.read(buffer);
        }
        fileChannel.close();
    }
    private void printFileContents(String path)
            throws IOException {
        FileReader fr = new FileReader(path);
        BufferedReader br = new BufferedReader(fr);
        String textRead = br.readLine();
        System.out.println("File contents: ");
        while (textRead != null) {
            System.out.println("     " + textRead);
            textRead = br.readLine();
         }
         fr.close();
         br.close();
    }
}

The output is:

File contents: 1234567890
Number of bytes read: 6
Buffer contents: 123456
Number of bytes read: 4
Buffer contents: 7890

From the output:

5. Writing to a File

This example shows the steps to write to a file through a file channel from a buffer source. Then the file contents are printed.

5.1. The input:

The input is a string. The string is converted to a byte array which is supplied to the buffer.

String input = "file channel example";
byte [] inputBytes = input.getBytes();

5.2. Create a buffer:

The file channel’s wrap() static method wraps a byte array into a buffer. The new buffer’s capacity and limit will be array.length and its initial position will be zero.

ByteBuffer buffer = ByteBuffer.wrap(inputBytes);

5.3. Create the channel:

The FileOutputStream‘s getChannel() method is used to create a channel. The method returns a file channel that is connected to the underlying file.

String filePath = "writefile.txt";
FileOutputStream fos = new FileOutputStream(filePath);
FileChannel fileChannel = fos.getChannel();

Note that in this example, initially the file does not exist. It is created by this program as shown in the above code snippet.

5.4. Write the buffer into the channel’s file:

The file channel’s write() method writes a sequence of bytes to this channel from the given buffer. Bytes are written starting at this channel’s current file position (in this case, zero).

int noOfBytesWritten = fileChannel.write(buffer);

5.5. Close resources:

Close the file channel and the file output stream.

fileChannel.close();
fos.close();

5.6. Print the file contents:

The file contents are printed to the terminal output.

Exceptions:

The following is the complete code for the example showing the writing to a file using file channel.

FileChannelWrite.java

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.io.FileReader;
import java.io.BufferedReader;
public class FileChannelWrite {
	public static void main (String [] args)
			throws Exception {
		new FileChannelWrite().writeFile();
	}
	private void writeFile()
			throws IOException {
		String input = "file channel example";
		System.out.print("Input string: " + input);
		byte [] inputBytes = input.getBytes();
		ByteBuffer buffer = ByteBuffer.wrap(inputBytes);
		String filePath = "writefile.txt";
		FileOutputStream fos = new FileOutputStream(filePath);
		FileChannel fileChannel = fos.getChannel();
		fileChannel.write(buffer);
		fileChannel.close();
		fos.close();
		printFileContents(filePath);
	}
	private void printFileContents(String path)
			throws IOException {
		FileReader fr = new FileReader(path);
		BufferedReader br = new BufferedReader(fr);
		String textRead = br.readLine();
		System.out.println("File contents: ");
		
		while (textRead != null) {
		
			System.out.println("     " + textRead);
			textRead = br.readLine();
		}
		fr.close();
		br.close();
	}
}

The output is:

Input string: file channel example
File contents: file channel example

From the output:

6. Download Java Source Code

This was an example of java.nio.channels.FileChannel.

Download
You can download the full source code of this example here: FileChannelExamples.zip
Exit mobile version