0%

java | bytebuffer 用法

介绍 bytebuffer

简单的使用

创建 data.txt 文件,内容为 1237878978798787800

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.redisc;

import lombok.extern.slf4j.Slf4j;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.ExecutionException;

@Slf4j(topic = "c.Test")
public class Run {

public static void main(String[] args) throws InterruptedException, ExecutionException {
// FileChannel
try (FileChannel channel = new FileInputStream("src/main/resources/data.txt").getChannel()) {
// 准备缓冲区
ByteBuffer buffer = ByteBuffer.allocate(10);
while (true) {
// 从 channel 读,向 buffer 写
int len = channel.read(buffer);
log.debug("读取到的字节数 {}", len);
if (len == -1) {
break;
}
//打印 buffer 的内容
buffer.flip(); // 切换到读模式
while (buffer.hasRemaining()) {//是否还有剩余的数据
byte b = buffer.get();
log.debug("实际字节 {}", (char) b);
}
buffer.clear(); // 切换为写模式
}

} catch (IOException e) {

}
}
}

输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
22:06:27.998 [main] DEBUG c.Test - 读取到的字节数 10
22:06:28.002 [main] DEBUG c.Test - 实际字节 1
22:06:28.002 [main] DEBUG c.Test - 实际字节 2
22:06:28.002 [main] DEBUG c.Test - 实际字节 3
22:06:28.002 [main] DEBUG c.Test - 实际字节 7
22:06:28.002 [main] DEBUG c.Test - 实际字节 8
22:06:28.002 [main] DEBUG c.Test - 实际字节 7
22:06:28.002 [main] DEBUG c.Test - 实际字节 8
22:06:28.002 [main] DEBUG c.Test - 实际字节 9
22:06:28.002 [main] DEBUG c.Test - 实际字节 7
22:06:28.002 [main] DEBUG c.Test - 实际字节 8
22:06:28.002 [main] DEBUG c.Test - 读取到的字节数 9
22:06:28.002 [main] DEBUG c.Test - 实际字节 7
22:06:28.002 [main] DEBUG c.Test - 实际字节 9
22:06:28.002 [main] DEBUG c.Test - 实际字节 8
22:06:28.002 [main] DEBUG c.Test - 实际字节 7
22:06:28.002 [main] DEBUG c.Test - 实际字节 8
22:06:28.002 [main] DEBUG c.Test - 实际字节 7
22:06:28.002 [main] DEBUG c.Test - 实际字节 8
22:06:28.002 [main] DEBUG c.Test - 实际字节 0
22:06:28.002 [main] DEBUG c.Test - 实际字节 0
22:06:28.002 [main] DEBUG c.Test - 读取到的字节数 -1

bytebuffer 正确使用姿势

  • buffer 写入数据
    • channel.read(buffer)
  • 调用 flip() 切换至读模式
  • buffer 读取数据
    • buffer.get()
  • 调用 clear() 或者 compact() 切换至写模式
  • 重复上述步骤

bytebuffer 内部结构

ByteBuffer 有以下重要属性

  • capacity
  • position
  • limit

一开始

写模式下,position 是写入位置,limit 等于容量,下面是写入 4 个字节的状态

flip 动作发生后,position 切换为读取位置,limit 切换为读取限制

读取 4 个字节后,状态

clear 动作发生后,状态

compact 方法,是把未读完的部分向前压缩,然后切换至写模式。「ab 已经读完」

请我喝杯咖啡吧~