codestory

Die Anleitung zu Java ReadableByteChannel

  1. ReadableByteChannel
  2. Methods
  3. read(ByteBuffer)
  4. Example 1
  5. Example 2

1. ReadableByteChannel

Wenn Sie gerade erst mit Java NIO beginnen, lesen Sie zuerst die folgenden Artikel, um mehr über die Grundlagen zu erfahren:
  • Java Nio
ReadableByteChannel ist eine Interface, die sich von der Interface Channel erstreckt, die Kanäle darstellt, die bytes von einem IO-Gerät lesen können.
public interface ReadableByteChannel extends Channel
ReadableByteChannel bietet nur eine Methode, die verwendet wird, um bytes in einen ByteBuffer einzulesen. Sie können diese Methode mehrmals aufrufen, um alle Daten aus dem Channel zu lesen.
public int read(ByteBuffer dst) throws IOException;
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 Kanaltyp können andere IO Operationen gleichzeitig mit der Leseoperation ausgeführt werden.
Hierarchie der Interface und Klassen in Bezug auf ReadableByteChannel:

2. Methods

ReadableByteChannel bietet im Vergleich zu seiner übergeordneten Interface nur eine weitere Methode.
public int read(ByteBuffer dst) throws IOException;
Andere Methoden, die von der Interface Channel geerbt wurden:
public boolean isOpen();  
public void close() throws IOException;

3. read(ByteBuffer)

public int read(ByteBuffer byteBuffer) throws IOException;
Die Methode read(ByteBuffer) liest eine Folge von bytes aus diesem ReadableByteChannel und weist dem ByteBuffer die Elemente zwischen position und limit-1 zu. Es wird so viel wie möglich gelesen und die Anzahl der gelesenen bytes zurückgegeben. Gibt -1 zurück, wenn das Ende des Kanals erreicht wurde.
  • Jedes dem ByteBuffer zugewiesene byte erhöht die Cursorposition um 1.
  • Bevor Sie diese Methode aufrufen, sollten Sie die Methode ByteBuffer.clear() aufrufen, um position = 0 und limit = capacity zu setzen.
  • Die maximale Anzahl von bytes, die in einem Aufruf dieser Methode gelesen werden können, ist byteBuffer.limit()-byteBuffer.position().
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 Kanaltyp können andere IO Operationen gleichzeitig mit der Leseoperation ausgeführt werden.

4. Example 1

Beispiel: Verwenden Sie ReadableByteChannel , um Daten aus einem InputStream zu lesen, insbesondere aus einem ByteArrayInputStream.
Unten sehen Sie ein Bild der bytes der Zeichenfolge "JP日本-八洲" im UTF-8-Format (UTF-8 verwendet 1, 2, 3 oder 4 bytes zum Speichern eines Zeichens).
ReadableByteChannel_ex1.java
package org.o7planning.readablebytechannel.ex;

import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;

public class ReadableByteChannel_ex1 {

    public static void main(String[] args) throws IOException {
        InputStream inputStream = null;
        ReadableByteChannel channel = null;
        try {
            byte[] byteData = "JP日本-八洲".getBytes("UTF-8");
            inputStream = new ByteArrayInputStream(byteData);
            
            // Create ReadableByteChannel to read a InputStream.
            channel = Channels.newChannel(inputStream);
            ByteBuffer buffer = ByteBuffer.allocate(10);

            int bytesRead = -1;
            while ((bytesRead = channel.read(buffer)) > -1) {
                System.out.println(" --- bytesRead : " + bytesRead + " ---- ");
                // Set limit = current position; position = 0;
                buffer.flip();

                while (buffer.hasRemaining()) {
                    byte b = buffer.get(); // [-128,127]
                    int charCode = Byte.toUnsignedInt(b); // [0,255] Java 8+
                    System.out.println((char) charCode + " --> " + charCode);
                }
                // Set position = 0; limit = capacity.
                buffer.clear();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeQuietly(inputStream);
            closeQuietly(channel);
        }
    }

    private static void closeQuietly(Closeable closeable) {
        try {
            closeable.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Output:
--- bytesRead : 10 ----
J --> 74
P --> 80
æ --> 230
— --> 151
¥ --> 165
æ --> 230
œ --> 156
¬ --> 172
- --> 45
å --> 229
 --- bytesRead : 5 ----
… --> 133
« --> 171
æ --> 230
´ --> 180
² --> 178
Sowohl InputStream als auch Channel implementieren oder erweitern die Interface Closeable, sodass sie automatisch geschlossen werden kann, wenn Sie die Syntax "Closeable-try-catch" verwenden. Und wir schreiben das obige Beispiel kürzer um.
ReadableByteChannel_ex1b.java
package org.o7planning.readablebytechannel.ex;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;

public class ReadableByteChannel_ex1b {

    public static void main(String[] args) throws IOException {
        byte[] byteData = "JP日本-八洲".getBytes("UTF-8");

        // Closeable-try-catch Syntax:
        try (InputStream inputStream = new ByteArrayInputStream(byteData);
                // Create ReadableByteChannel to read a InputStream.
                ReadableByteChannel channel = Channels.newChannel(inputStream);) { // try
            ByteBuffer buffer = ByteBuffer.allocate(10);

            int bytesRead = -1;
            while ((bytesRead = channel.read(buffer)) > -1) {
                System.out.println(" --- bytesRead : " + bytesRead + " ---- ");
                // Set limit = current position; position = 0;
                buffer.flip();

                while (buffer.hasRemaining()) {
                    byte b = buffer.get(); // [-128,127]
                    int charCode = Byte.toUnsignedInt(b); // [0,255] Java 8+
                    System.out.println((char) charCode + " --> " + charCode);
                }
                // Set position = 0; limit = capacity.
                buffer.clear();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5. Example 2

Zum Beispiel: Lesen einer Datendatei im Netzwerk.
ReadableByteChannel_ex2.java
String urlString = "https://s3.o7planning.com/txt/utf8-file-without-bom.txt";
URL url = new URL(urlString);

try (InputStream inputStream = url.openStream();
        // Create ReadableByteChannel to read a InputStream.
        ReadableByteChannel channel = Channels.newChannel(inputStream);) { // try
    
    ByteBuffer buffer = ByteBuffer.allocate(10);
    int bytesRead = -1;
    while ((bytesRead = channel.read(buffer)) > -1) {
        System.out.println(" --- bytesRead : " + bytesRead + " ---- ");
        // Set limit = current position; position = 0;
        buffer.flip();

        while (buffer.hasRemaining()) {
            byte b = buffer.get(); // [-128,127]
            int charCode = Byte.toUnsignedInt(b); // [0,255] Java 8+
            System.out.println((char) charCode + " --> " + charCode);
        }
        // Set position = 0; limit = capacity.
        buffer.clear();
    }
} catch (Exception e) {
    e.printStackTrace();
}
Output:
--- bytesRead : 10 ----
J --> 74
P --> 80
æ --> 230
— --> 151
¥ --> 165
æ --> 230
œ --> 156
¬ --> 172
- --> 45
å --> 229
 --- bytesRead : 5 ----
… --> 133
« --> 171
æ --> 230
´ --> 180
² --> 178