o7planning

Java ScatteringByteChannel Tutorial with Examples

  1. ScatteringByteChannel
  2. Methods
  3. read(ByteBuffer[])
  4. read(ByteBuffer[], int, int)
  5. Example 1

1. ScatteringByteChannel

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, ReadableByteChannel is an interface that provides a method to read bytes and assign them to the elements of a ByteBuffer. ScatteringByteChannel is an extension of ReadableByteChannel that provides methods for scattering read. In a single call, the bytes read will be assigned to the elements of multiple ByteBuffer(s).
public interface ScatteringByteChannel extends ReadableByteChannel
ScatteringByteChannel channel = ...; // (ScatteringByteChannel)Channels.newChannel(fileIS);
ByteBuffer[] buffers = new ByteBuffer[]{buf1, buf2, buf3};
channel.read(buffers);
Hierarchy of interfaces and classes relating to ScatteringByteChannel:

2. Methods

The methods are defined in the ScatteringByteChannel interface:
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;
    
public long read(ByteBuffer[] dsts) throws IOException;
The methods inherited from the ReadableByteChannel interface:
public int read(ByteBuffer dst) throws IOException;
The methods inherited from the Channel interface:
public boolean isOpen();  
public void close() throws IOException;

3. read(ByteBuffer[])

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

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

public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;
Reads a sequence of bytes from this ScatteringByteChannel and assigns to the elements of the given ByteBuffer(s). The method returns the number of bytes read, or returns -1 if the end of the channel has been reached.
Calling this method is equivalent to:
ByteBuffer[] dsts2 = new ByteBuffer[] {dsts[offset], dsts[offset+1], .., dsts[offset+length-1]};  

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

5. Example 1

Example: Using ScatteringByteChannel to read a file:
test-file.txt
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
ScatteringByteChannel_ex1.java
package org.o7planning.scatteringbytechannel.ex;

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

public class ScatteringByteChannel_ex1 {

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

    public static void main(String[] args) throws IOException {
        try (FileInputStream fis = new FileInputStream(filePath);
                ScatteringByteChannel channel = (ScatteringByteChannel) Channels.newChannel(fis);) {

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

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

            channel.read(buffers);

            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();
                while (buffer.hasRemaining()) {
                    byte b = buffer.get();
                    int charCode = Byte.toUnsignedInt(b);
                    System.out.println((char) charCode + " --> " + charCode);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Output:
--- buffer[0] ---
a --> 97
b --> 98
c --> 99
d --> 100
e --> 101
f --> 102
g --> 103
h --> 104
i --> 105
j --> 106
 --- buffer[1] ---
k --> 107
l --> 108
m --> 109
n --> 110
o --> 111
p --> 112
q --> 113
r --> 114
s --> 115
t --> 116
u --> 117
v --> 118
w --> 119
x --> 120
y --> 121
 --- buffer[2] ---
z --> 122
A --> 65
B --> 66
C --> 67
D --> 68
E --> 69
F --> 70
G --> 71
H --> 72
I --> 73