FileChannel

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.
 
 
 
 
 
 

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:

  • File contents: 1234567890; this is the text in the file.
  • Number of bytes read: 6, Buffer contents: 123456. This is the first read. The first 6 bytes are read from the channel into the buffer and the contents in the buffer are 123456.
    NOTE: At this point the buffer and file channel positions are same: 6. The buffer’s flip() method changes its position to zero.
  • Number of bytes read: 4, Buffer contents: 7890. This is the subsequent (and last) read. The remaining 4 bytes are read and printed.
    NOTE: Now the channel’s position is 10 and the buffer’s position is 4.

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:

  • FileOutputStream‘s constructor throws FileNotFoundException.
  • FileChannel‘s write(), close() and FileOutputStream‘s close() methods throw IOException.

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:

  • Input string: file channel example; this is the input to the buffer from which it is written to the file.
  • File contents: file channel example; this is the contents from the file written to from the source buffer. Note that the contents of the input string and the file are same – file channel example

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

Prasad Saya

Prasad Saya is a software engineer with over ten years’ experience in application development, maintenance, testing and consulting on various platforms. He is a certified Java and Java EE developer. At present his interest is in developing Java applications. He also has experience working with databases and ERP applications.
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