Java NIO FileChannel Tutorial

Java NIO FileChannel Tutorial

FileChannel belongs to the java.nio.channels package and is used for reading, writing, mapping, and manipulating a file. FileChannels implement SeekableByteChannel which allows portion within the file to be either queried or modified.

Although some channels like ServerSocketChannel can be put into non-blocking mode, FileChannels can only operating in blocking mode.

Topics Covered in this Tutorial

  1. What are FileChannels
  2. Opening a FileChannel
    1. Opening a FileChannel from FileInputStream
    2. Opening a FileChannel from FileOutputStream
    3. Opening a FileChannel using RandomAccessFile
    4. Opening a FileChannel using Path
  3. Reading Data from FileChannel
  4. Writing Data to FileChannel
  5. Getting FileChannel Size
  6. Locking a File using FileLock
  7. Truncating a FileChannel

What are FileChannels

FileChannels are used for reading and writing data using file I/O. FileChannels cannot be created directly. An instance of FileChannel must be obtained by either using the getChannel() method or by calling open() method from FileChannel class.

Opening a FileChannel

A file channel is created by invoking one of the open methods defined by this class. A file channel can also be obtained from an existing FileInputStream, FileOutputStream, or RandomAccessFile object by invoking that object’s getChannel method, which returns a file channel that is connected to the same underlying file.

Opening a FileChannel from FileInputStream

FileInputStream inputStream = new FileInputStream("C:\\tmp\\testfile.txt");
FileChannel channel = inputStream.getChannel();

Opening a FileChannel from FileOutputStream

FileOutputStream outputStream = new FileOutputStream("C:\\tmp\\output.txt");
FileChannel channel = outputStream.getChannel();

Opening a FileChannel using RandomAccessFile

RandomAccessFile outfile = new RandomAccessFile("C:\\tmp\\output.txt", "rw");
SeekableByteChannel fileChannel = outfile.getChannel();

Opening a FileChannel using Path

Path path = Paths.get("C:\\tmp\\testfile.txt");
FileChannel channel = FileChannel.open(path,
                                        StandardOpenOption.CREATE_NEW,
                                        StandardOpenOption.WRITE);

Reading Data from FileChannel

package com.avaldes.tutorial;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class MyBufferReadExample {
 private static final int BUFFER_SIZE = 1024;
 private static final String FILE_NAME = "c:\\tmp\\testfile.txt";

 public static void main(String[] args) throws IOException {
  System.out.println("Starting MyBufferReadExample...");
  FileInputStream fileIS = new FileInputStream(FILE_NAME);
  FileChannel inChannel = fileIS.getChannel();

  try {
   ByteBuffer myBuffer = ByteBuffer.allocate(BUFFER_SIZE);

   while (inChannel.read(myBuffer) > 0) {
    myBuffer.flip();

    while (myBuffer.hasRemaining()) {
     System.out.print((char) myBuffer.get());
    }
    myBuffer.clear();
   }
  } finally{
   inChannel.close();
   fileIS.close();
  }
 }
}

Writing Data to FileChannel

In this example, we use FileOutputStream and the getChannel() method to obtain a FileChannel.

package com.avaldes.tutorial;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import org.apache.log4j.Logger;

public class MyBufferWriteExample {
  private static final Logger logger
      = Logger.getLogger(MyBufferWriteExample.class);
  private static final int BUFFER_SIZE = 1024;
  private static final String FILE_NAME
      = "c:\\tmp\\output.txt";
  private static final String QUOTE
      = "If your actions inspire others to dream more, learn "
      + "more, do more and become more, you are a leader.";

  public static void main(String[] args) throws IOException {
    logger.info("Starting MyBufferWriteExample...");
    FileOutputStream fileOS = new FileOutputStream(FILE_NAME);
    FileChannel outChannel = fileOS.getChannel();

    try {
      ByteBuffer myBuffer = ByteBuffer.allocate(BUFFER_SIZE);
      myBuffer.put(QUOTE.getBytes());
      myBuffer.flip();

      int bytesWritten = outChannel.write(myBuffer);
      logger.info(
        String.format("%d bytes written to disk...", bytesWritten));
      logger.info(
        String.format("Current buffer limit=>[%d]", myBuffer.limit()));
      logger.info(
        String.format("Current buffer position=>[%d]", myBuffer.position()));
    } finally  {
      outChannel.close();
      fileOS.close();
    }
  }
}

Getting FileChannel Size

RandomAccessFile file = new RandomAccessFile("C:\\tmp\\output.txt", "rw");
SeekableByteChannel fileChannel = file.getChannel();

long size = fileChannel.size();
System.out.println("FileChannel Size....: " + size);

Locking a File using FileLock

Allows us to lock all or a portion of the filechannel’s underlying file. A FileLock object when a lock is acquired on a file by using either the lock or tryLock methods of the FileChannel class.

Locking the complete file using exclusive lock

ParametersDescription
positionThe position at which the locked region is to start; must be non-negative
sizeThe size of the locked region; must be non-negative, and the sum position + size must be non-negative
sharedIf true, then request is a shared lock; allows the channel to be open for reading (and possibly writing). If set the false, the request is an exclusive lock; requires the channel must be open for writing (and possibly reading)
FileLock lock = fc.lock(0, Long.MAX_VALUE, true);

Truncating a FileChannel

Truncates this channel’s file to the given size. If the size provided is less than the file’s current size then the file is truncated, discarding all bytes beyond the new end of the file. If the size provided is greater than or equal to the file’s current size then the file is not modified.

RandomAccessFile infile = new RandomAccessFile(FILE_NAME, "rw");
SeekableByteChannel fileChannel = infile.getChannel();
fileChannel.truncate(10000);

Truncating a FileChannel to 10000 bytes

package com.avaldes.tutorial;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.SeekableByteChannel;

public class MyFileChannelTruncateExample {
 private static final int TRUNCATE_SIZE = 10000;
 private static final String FILE_NAME = "c:\\tmp\\testfile.txt";

 public static void main(String[] args) throws IOException {
  System.out.println("Starting MyBufferReadExample...");
  RandomAccessFile infile = new RandomAccessFile(FILE_NAME, "rw");
  SeekableByteChannel fileChannel = infile.getChannel();

  long orig_size = fileChannel.size();
  System.out.println("Original FileChannel Size....: " + orig_size);
  fileChannel.truncate(TRUNCATE_SIZE);
  long new_size = fileChannel.size();
  System.out.println("After Truncate FileChannel Size....: " + new_size);

  infile.close();
  fileChannel.close();
 }
}

Output from Truncating a FileChannel Example

Starting MyBufferReadExample...
Original FileChannel Size....: 16671
After Truncate FileChannel Size....: 10000

That’s It!

I hope you enjoyed this tutorial. It was certainly a lot of fun putting it together and testing it out. Please continue to share the love and like us so that we can continue bringing you quality tutorials. Happy Coding!!!

java_nio_filechannel

Java NIO Related Tutorials

  • Java NIO Tutorial
    In this tutorial series we discuss the new features of Java NIO.
  • Java NIO Buffers
    This post covers NIO Buffers in more detail and provides practical examples of using buffers in real world applications.
  • Java NIO Channels
    This post covers NIO Channels in more detail and provides examples on network connections and Java I/O in relation to files.
  • Java NIO Selectors
    In this tutorial we learn how to use the Selector class from the java.io.channels package library to build High-Performance I/O client-server using NIO.
  • Java NIO File Channel
    In this tutorial we learn how to use the FileChannel class from the java.io.channels package library and provide working examples on all of the main methods.
  • Java NIO Socket Channel
    In this tutorial we learn how to use the SocketChannel and how it is used for reading/writing stream oriented data and using TCP connection based protocol.
  • Java NIO DatagramChannel Tutorial
    In this tutorial we learn how to use the DatagramChannel to allow developers to build high-performant data streaming applications that send and receive datagrams using a protocol called UDP.
  • Java NIO and NIO2 Path Tutorial
    This tutorial will introduce the Path interface and many of its methods. The Path interface was made available as part of the Java SE 7 release in the Java NIO 2 File API.

Please Share Us on Social Media

Facebooktwitterredditpinterestlinkedinmail

Leave a Reply

Your email address will not be published. Required fields are marked *