betacode

Руководство Java ScatteringByteChannel

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

1. ScatteringByteChannel

Если вы только начинаете работать с Java NIO, сначала прочитайте следующие статьи, чтобы узнать больше об основах:
  • Java Nio
Как вы знаете, ReadableByteChannel - это интерфейс, который предоставляет метод для чтения bytes и присвоения их элементам ByteBuffer. ScatteringByteChannel - это расширение ReadableByteChannel, которое предоставляет методы для чтения рассеяния (scattering read). В одном вызове считанные bytes будут присвоены элементам нескольких ByteBuffer(s).
public interface ScatteringByteChannel extends ReadableByteChannel
ScatteringByteChannel channel = ...; // (ScatteringByteChannel)Channels.newChannel(fileIS);
ByteBuffer[] buffers = new ByteBuffer[]{buf1, buf2, buf3};
channel.read(buffers);
Иерархия интерфейсов и классов, относящихся к ScatteringByteChannel:

2. Methods

Методы определены в interface ScatteringByteChannel:
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;
    
public long read(ByteBuffer[] dsts) throws IOException;
Методы, унаследованные от interface ReadableByteChannel:
public int read(ByteBuffer dst) throws IOException;
Методы, унаследованные от interface Channel:
public boolean isOpen();  
public void close() throws IOException;

3. read(ByteBuffer[])

public long read(ByteBuffer[] dsts) throws IOException;
Считывает последовательность bytes из этого ScatteringByteChannel и присваивает элементам заданного ByteBuffer(s). Метод возвращает количество прочитанных bytes или возвращает -1, если достигнут конец канала.
Вызов этого метода эквивалентен:
scatteringByteChannel.write(dsts, 0, dsts.length);
Одновременно может выполняться только одна операция чтения на Channel. Это означает, что если один thread инициирует операцию чтения на Channel, другие thread не могут читать на этом Channel, они блокируются (block) до завершения операции. Другие операции IO могут выполняться одновременно с операцией чтения в зависимости от типа Channel.

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

public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;
Считывает последовательность bytes из ScatteringByteChannel и присваивает элементам заданного ByteBuffer(s). Метод возвращает количество прочитанных bytes или возвращает -1, если достигнут конец канала.
Вызов этого метода эквивалентен:
ByteBuffer[] dsts2 = new ByteBuffer[] {dsts[offset], dsts[offset+1], .., dsts[offset+length-1]};  

scatteringByteChannel.read(dsts2);
Одновременно может выполняться только одна операция чтения на Channel. Это означает, что если один thread инициирует операцию чтения на Channel, другие thread не могут читать на этом Channel, они блокируются (block) до завершения операции. Другие операции IO могут выполняться одновременно с операцией чтения в зависимости от типа Channel.

5. Example 1

Например: Использование ScatteringByteChannel для чтения файла:
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