codestory

Die Anleitung zu Java ScatteringByteChannel

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

1. ScatteringByteChannel

Wenn Sie gerade erst mit Java NIO beginnen, lesen Sie zuerst die folgenden Artikel, um mehr über die Grundlagen zu erfahren:
  • Java Nio
Wie Sie wissen, ist ReadableByteChannel eine Interface, die eine Methode zum Lesen von bytes und deren Zuweisung zu den Elementen eines ByteBuffer bereitstellt. ScatteringByteChannel ist eine Erweiterung von ReadableByteChannel, die Methoden zum Streuen von Lesevorgängen (scattering read) bereitstellt. In einem einzigen Aufruf werden die gelesenen bytes den Elementen mehrerer ByteBuffer(s) zugewiesen.
public interface ScatteringByteChannel extends ReadableByteChannel
ScatteringByteChannel channel = ...; // (ScatteringByteChannel)Channels.newChannel(fileIS);
ByteBuffer[] buffers = new ByteBuffer[]{buf1, buf2, buf3};
channel.read(buffers);
Hierarchie der Interfaces und Klassen zu ScatteringByteChannel:

2. Methods

Die Methoden sind in Interface ScatteringByteChannel definiert:
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;
    
public long read(ByteBuffer[] dsts) throws IOException;
Die von der Interface ReadableByteChannel geerbten Methoden:
public int read(ByteBuffer dst) throws IOException;
Die von der Interface Channel geerbten Methoden:
public boolean isOpen();  
public void close() throws IOException;

3. read(ByteBuffer[])

public long read(ByteBuffer[] dsts) throws IOException;
Lesen Sie eine Folge von bytes aus diesem ScatteringByteChannel und weist sie den Elementen der angegebenen ByteBuffer(s) zu. Die Methode gibt die Anzahl der gelesenen bytes zurück oder gibt -1 zurück, wenn das Ende des Kanals erreicht wurde.
Der Aufruf dieser Methode ist äquivalent zu:
scatteringByteChannel.write(dsts, 0, dsts.length);
Es kann jeweils nur eine Leseoperation auf dem Channel stattfinden. Dies bedeutet, dass, wenn ein Thread eine Leseoperation auf einem Channel einleitet, andere Threads auf diesem Channel nicht lesen können, sie werden blockiert, bis die Operation abgeschlossen ist. Je nach Typ vom Channel können andere IO Operationen gleichzeitig mit der Leseoperation ausgeführt werden.

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

public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;
Liest eine Folge von bytes aus diesem ScatteringByteChannel und weist sie den Elementen der angegebenen ByteBuffer(s) zu. Die Methode gibt die Anzahl der gelesenen bytes zurück oder gibt -1 zurück, wenn das Ende des Kanals erreicht wurde.
Der Aufruf dieser Methode ist äquivalent zu:
ByteBuffer[] dsts2 = new ByteBuffer[] {dsts[offset], dsts[offset+1], .., dsts[offset+length-1]};  

scatteringByteChannel.read(dsts2);
Es kann jeweils nur eine Leseoperation auf dem Channel stattfinden. Dies bedeutet, dass, wenn ein Thread eine Leseoperation auf einem Channel einleitet, andere Threads auf diesem Channel nicht lesen können, sie werden blockiert, bis die Operation abgeschlossen ist. Je nach Typ vom Channel können andere IO Operationen gleichzeitig mit der Leseoperation ausgeführt werden.

5. Example 1

Beispiel: Verwenden von ScatteringByteChannel zum Lesen einer Datei:
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