As in normal Java applications where IO happens mostly between an input source and output target, in NIO as well we may need to transfer data from one channel to another channel very frequently.
Bulk transfers of file data from one place to another is so common that a couple of optimization methods have been added to the FileChannel
class to make it even more efficient.
1. Data Transfer between Channels
Java NIO provides two methods for transferring the data between two channels:
- FileChannel.transferTo()
- FileChannel.transferFrom()
The transferTo()
and transferFrom()
methods allow us to cross-connect one channel to another. This eliminates the need to pass the data through an intermediate buffer.
These methods exist only on the FileChannel
class, so one of the channels involved in a channel-to-channel transfer must be a FileChannel
.
public abstract class FileChannel extends AbstractChannel implements ByteChannel, GatheringByteChannel, ScatteringByteChannel { // There are more other methods public abstract long transferTo (long position, long count, WritableByteChannel target); public abstract long transferFrom (ReadableByteChannel src, long position, long count); }
We can’t do direct transfers between socket channels, but socket channels implement
WritableByteChannel
andReadableByteChannel
, so the content of a file can be transferred to a socket withtransferTo()
, or data can be read from a socket directly into a file withtransferFrom()
.
Also, keep in mind that these methods may throw java.io.IOException
if any error is encountered during the transfer.
Channel-to-channel transfers can potentially be extremely fast, especially where the underlying operating system provides native support. Some operating systems can perform direct transfers without ever passing the data through user-space. This can be a huge win for high-volume data transfer.
2. FileChannel transferTo() and transferFrom() Example
In this example, we are reading the file content from 3 different files and writing their combined output into a fourth file.
package com.howtodoinjava.nio; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.channels.FileChannel; import java.nio.channels.WritableByteChannel; public class ChannelTransferExample { public static void main(String[] argv) throws Exception { //Input files String[] inputFiles = new String[]{"inputFile1.txt","inputFile2.txt","inputFile3.txt"}; //Files contents will be written in these files String outputFile = "outputFile.txt"; //Get channel for output file FileOutputStream fos = new FileOutputStream(new File(outputFile)); WritableByteChannel targetChannel = fos.getChannel(); for (int i = 0; i < inputFiles.length; i++) { //Get channel for input files FileInputStream fis = new FileInputStream(inputFiles[i]); FileChannel inputChannel = fis.getChannel(); //Transfer data from input channel to output channel inputChannel.transferTo(0, inputChannel.size(), targetChannel); //close the input channel inputChannel.close(); fis.close(); } //finally close the target channel targetChannel.close(); fos.close(); } }
Drop your comments and suggestions in the comments section.
Happy Learning !!
Comments