Last Updated on 29 July 2019   |   Print Email
In this Java File IO tutorial, you will learn how to use random access file with the Java NIO API.The SeekableByteChannel interface defines the following operations for reading and writing data at any position in a file:
position(): returns the current position of the file pointer in the channel.
position(long pos): sets the current position of the file pointer in the channel.
read(ByteBuffer buffer): reads a sequence of bytes from the channel to a given buffer. This method returns the number of bytes read, or -1 if the channel has reached the end of the stream.
write(ByteBuffer buffer): writes a sequence of bytes to the channel from a given buffer. This method returns the number of bytes written.
The FileChannel class is an implementation of the SeekableByteChannel interface, so you can open a FileChannel for performing random access file operations like this:
This opens a file for both reading and writing. The READ and WRITE are two values of the enum StandardOpenOption.Then you can call the position() method to move the file pointer to a specified location where you want to read or write data. For example:
fileChannel.position(128);
This moves the file pointer to the byte 128th in the file. Then you can read a chunk of data from the channel to a buffer like this:
ByteBuffer buffer = ByteBuffer.allocate(30);
do {
fileChannel.read(buffer);
} while (buffer.hasRemaining());
This reads 30 bytes from the current position to a byte buffer.For writing, the following code writes data from a byte buffer to the channel:
String text = "Some text";
ByteBuffer buffer = ByteBuffer.wrap(text.getBytes());
while (buffer.hasRemaining()) {
fc.write(buffer);
}
This puts a String to a byte buffer, which is then written to the channel.Let’s see a couple of realistic examples that use the random access file functionality of the FileChannel class to read and write ID3 tags (song name, album, artist, etc) of a MP3 file.The following program opens a MP3 file to read its metadata (song name, artist, album and year) in ID3v1 format:
import java.io.*;
import java.nio.*;
import java.nio.file.*;
import static java.nio.file.StandardOpenOption.*;
import java.nio.channels.*;
/**
* How to use FileChannel's random access file functionality to read
* metadata of an MP3 file.
*
* @author www.codejava.net
*/
public class ReadMP3Tags {
public void read(String filePath) {
Path file = Paths.get(filePath);
ByteBuffer buffer = null;
try (FileChannel fc = FileChannel.open(file, READ))
{
fc.position(fc.size() - 128);
buffer = ByteBuffer.allocate(3);
do {
fc.read(buffer);
} while (buffer.hasRemaining());
String tag = new String(buffer.array());
if (!"TAG".equals(tag)) {
System.out.println("This file doesn't support ID3v1");
System.exit(0);
}
buffer = ByteBuffer.allocate(30);
do {
fc.read(buffer);
} while (buffer.hasRemaining());
String songName = new String(buffer.array());
System.out.println("Song name: " + songName);
buffer.clear();
do {
fc.read(buffer);
} while (buffer.hasRemaining());
String artist = new String(buffer.array());
System.out.println("Artist: " + artist);
buffer.clear();
do {
fc.read(buffer);
} while (buffer.hasRemaining());
String album = new String(buffer.array());
System.out.println("Album: " + artist);
buffer = ByteBuffer.allocate(4);
do {
fc.read(buffer);
} while (buffer.hasRemaining());
String year = new String(buffer.array());
System.out.println("Year: " + year);
} catch (IOException ex) {
System.err.println("I/O Error: " + ex);
}
}
public static void main(String[] args) {
String filePath = args[0];
new ReadMP3Tags().read(filePath);
}
}
Run this program like this:
java ReadMP3Tags <mp3_file_path>
For example:
java ReadMP3Tags Love.mp3
As you can see, this program starts reading the metadata at the beginning of the last 128 bytes in the file. It reads 3 bytes to check if it matches the string “TAG” which is the identifier for ID3v1 format. Then it reads 3 attributes (song name, artist and album) with each as a block of 30 bytes, and reads the year as a block of 4 bytes.The output could be:
Song name: Love Like A Dream
Artist: Lara Fabian, Igor Krutoy
Album: Lara Fabian, Igor Krutoy
Year: 2011
And the following sample program opens a MP3 file to update the song name:
import java.io.*;
import java.nio.*;
import java.nio.file.*;
import static java.nio.file.StandardOpenOption.*;
import java.nio.channels.*;
/**
* How to use FileChannel's random access file functionality to update
* metadata of an MP3 file.
*
* @author www.codejava.net
*/
public class WriteMP3Tags {
public void updateSongName(String filePath, String songName) {
Path file = Paths.get(filePath);
ByteBuffer buffer = null;
try (FileChannel fc = FileChannel.open(file, READ, WRITE))
{
fc.position(fc.size() - 128);
buffer = ByteBuffer.allocate(3);
do {
fc.read(buffer);
} while (buffer.hasRemaining());
String tag = new String(buffer.array());
if (!"TAG".equals(tag)) {
System.out.println("This file doesn't support ID3v1");
System.exit(0);
}
buffer = ByteBuffer.wrap(songName.getBytes());
while (buffer.hasRemaining()) {
fc.write(buffer);
}
fc.close();
} catch (IOException ex) {
System.err.println("I/O Error: " + ex);
}
}
public static void main(String[] args) {
String filePath = args[0];
String songName = args[1];
new WriteMP3Tags().updateSongName(filePath, songName);
}
}
Run this program like this:
java WriteMP3Tags <mp3_file_path> <song_name>
For example:
java WriteMP3Tags Love.mp3 “Love Like My Dream”
You can run the ReadMP3Tags program to verify the result.
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.
Comments