o7planning

Java GatheringByteChannel Tutorial with Examples

  1. GatheringByteChannel
  2. Methods
  3. write(ByteBuffer[])
  4. write(ByteBuffer[], int, int)
  5. Example 1

1. GatheringByteChannel

If you are just getting started with Java NIO, read the following articles first to understand more about the basics:
  • Java Nio
As you know, WritableByteChannel is an interface that provides a method to write bytes from a ByteBuffer. GatheringByteChannel is an extension from WritableByteChannel that provides methods for gathering write. In a single call, bytes from multiple ByteBuffer(s) will be written to the GatheringByteChannel.
public interface GatheringByteChannel extends WritableByteChannel
GatheringByteChannel channel =...; // (GatheringByteChannel)Channels.newChannel(fileOS);
ByteBuffer[] buffers = new ByteBuffer[]{buf1, buf2, buf3};
channel.write(buffers);
Hierarchy of interfaces and classes relating to GatheringByteChannel:

2. Methods

The methods are defined in the GatheringByteChannel interface:
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException;

public long write(ByteBuffer[] srcs) throws IOException;
The methods inherited from the WritableByteChannel interface:
public int write(ByteBuffer src) throws IOException;
The methods inherited from the Channel interface:
public boolean isOpen();  
public void close() throws IOException;

3. write(ByteBuffer[])

public long write(ByteBuffer[] srcs) throws IOException;
Writes a sequence of bytes to this GatheringByteChannel from many given ByteBuffer(s). The method returns the number of bytes written or returns -1 if the end of the channel has been reached.
Calling this method is equivalent to:
gatheringByteChannel.write(srcs, 0, srcs.length);
Only one recording operation on the Channel can take place at a time. This means that if one thread is initiating a write operation on a Channel, other threads cannot write on this Channel, they are blocked until the operation is completed. Other IO operations can be performed concurrently with the write operation depending on the Channel type.

4. write(ByteBuffer[], int, int)

public long write(ByteBuffer[] srcs, int offset, int length) throws IOException;
Write a sequence of bytes to this GatheringByteChannel from an array of ByteBuffer(s), from the index offset to offset+length-1. The method returns the number of bytes written or returns -1 if the end of the channel has been reached.
Calling this method is equivalent to:
ByteBuffer[] srcs2 = new ByteBuffer[] {srcs[offset], srcs[offset+1], .., srcs[offset+length-1]};

gatheringByteChannel.write(srcs2);
Only one recording operation on the Channel can take place at a time. This means that if one thread is initiating a write operation on a Channel, other threads cannot write on this Channel, they are blocked until the operation is completed. Other IO operations can be performed concurrently with the write operation depending on the Channel type.

5. Example 1

Example: Write a program that copies file, uses ScatteringByteChannel to read the input file and uses GatheringByteChannel to write the file.
GatheringByteChannel_ex1.java
package org.o7planning.gatheringbytechannel.ex;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;

public class GatheringByteChannel_ex1 {

    // Windows: C:/somepath/test-file.txt
    private static final String inputFilePath = "/Volumes/Data/test/in-file.txt";

    private static final String outputFilePath = "/Volumes/Data/test/out-file.txt";

    public static void main(String[] args) throws IOException {
        try (// Input:
                FileInputStream fis = new FileInputStream(inputFilePath);
                ScatteringByteChannel inChannel = (ScatteringByteChannel) Channels.newChannel(fis);
                // Output:
                FileOutputStream fos = new FileOutputStream(outputFilePath);
                GatheringByteChannel outChannel = (GatheringByteChannel) Channels.newChannel(fos);) { // try

            ByteBuffer buf1 = ByteBuffer.allocate(10);
            ByteBuffer buf2 = ByteBuffer.allocate(15);
            ByteBuffer buf3 = ByteBuffer.allocate(10);

            ByteBuffer[] buffers = new ByteBuffer[] { buf1, buf2, buf3 };

            long bytesRead = -1;
            while ((bytesRead = inChannel.read(buffers)) != -1) {
                for (int i = 0; i < buffers.length; i++) {
                    System.out.println(" --- buffer[" + i + "] ---");
                    ByteBuffer buffer = buffers[i];
                    // Set limit = current position; position = 0;
                    buffer.flip();
                    outChannel.write(buffer);
                    buffer.clear();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}