openplanning

Hướng dẫn và ví dụ Java ScatteringByteChannel

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

1. ScatteringByteChannel

Nếu bạn mới bắt đầu với Java NIO, hãy đọc trước các bài viết dưới đây để hiểu thêm về các khái niệm cơ bản:
  • Hướng dẫn và ví dụ Java Nio (Java New IO)
Như đã biết, ReadableByteChannel là một interface cung cấp phương thức để đọc các bytes và gán vào các phần tử của một ByteBuffer. ScatteringByteChannel là một mở rộng từ ReadableByteChannel, cung cấp các phương thức cho việc đọc phân tán (scattering read). Trong một lần gọi, các bytes đọc được sẽ được gán vào các phần tử của nhiều ByteBuffer(s).
public interface ScatteringByteChannel extends ReadableByteChannel
ScatteringByteChannel channel = ...; // (ScatteringByteChannel)Channels.newChannel(fileIS);
ByteBuffer[] buffers = new ByteBuffer[]{buf1, buf2, buf3};
channel.read(buffers);
Hệ thống phân cấp các interface và các lớp có liên quan tới ScatteringByteChannel:

2. Methods

Các phương thức được định nghĩa trong interface ScatteringByteChannel:
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;
    
public long read(ByteBuffer[] dsts) throws IOException;
Các phương thức thừa kế từ interface ReadableByteChannel:
public int read(ByteBuffer dst) throws IOException;
Các phương thức thừa kế từ interface Channel:
public boolean isOpen();  
public void close() throws IOException;

3. read(ByteBuffer[])

public long read(ByteBuffer[] dsts) throws IOException;
Đọc một dẫy các bytes từ ScatteringByteChannel này và gán vào các phần tử của các ByteBuffer(s) đã cho. Phương thức trả về số bytes đã đọc được hoặc trả về -1 nếu đã tiến tới cuối kênh.
Việc gọi phương thức này tương đương với:
scatteringByteChannel.write(dsts, 0, dsts.length);
Tại một thời điểm chỉ một hoạt động đọc trên Channel được diễn ra. Điều này có nghĩa là nếu một thread đang bắt đầu thao tác đọc trên một Channel thì các thread khác không thể đọc trên Channel này, chúng bị chặn (block) cho tới khi hoạt động này hoàn thành. Các hoạt động IO khác có thể tiến hành đồng thời với hoạt động đọc hay không phụ thuộc vào loại Channel.

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

public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;
Đọc một dẫy các bytes từ ScatteringByteChannel này và gán vào các phần tử của các ByteBuffer(s) đã cho. Phương thức trả về số bytes đã đọc được hoặc trả về -1 nếu đã tiến tới cuối kênh.
Việc gọi phương thức này tương đương với:
ByteBuffer[] dsts2 = new ByteBuffer[] {dsts[offset], dsts[offset+1], .., dsts[offset+length-1]};  

scatteringByteChannel.read(dsts2);
Tại một thời điểm chỉ một hoạt động đọc trên Channel được diễn ra. Điều này có nghĩa là nếu một thread đang bắt đầu thao tác đọc trên một Channel thì các thread khác không thể đọc trên Channel này, chúng bị chặn (block) cho tới khi hoạt động này hoàn thành. Các hoạt động IO khác có thể tiến hành đồng thời với hoạt động đọc hay không phụ thuộc vào loại Channel.

5. Example 1

Ví dụ: Sử dụng ScatteringByteChannel để đọc một 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