0%

java | bytebuffer 方法演示

bytebuffer 方法演示。

引入自写的方法类。

下载 JAVA 文件

netty 包

1
2
3
4
5
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.86.Final</version>
</dependency>

position 位置

这个要结合 java | bytebuffer 用法 | bytebuffer 内部结构

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
package com.redisc;

import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;

import static com.redisc.ByteBufferUtil.debugAll;

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

public static void main(String[] args) {
ByteBuffer buffer = ByteBuffer.allocate(10);

buffer.put((byte) 0x61); // 'a'
debugAll(buffer);
buffer.put(new byte[]{0x62, 0x63}); // 'abc'
debugAll(buffer);
buffer.flip(); // position 指向 0
System.out.println(buffer.get()); // 输出 a
debugAll(buffer);
buffer.compact(); // 把 a 去除,后面的补上来 position 指向 2
debugAll(buffer);
buffer.put(new byte[]{0x65}); // 'bce'
debugAll(buffer);
}
}

输出

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
+--------+-------------------- all ------------------------+----------------+
position: [1], limit: [10]
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 61 00 00 00 00 00 00 00 00 00 |a......... |
+--------+-------------------------------------------------+----------------+
+--------+-------------------- all ------------------------+----------------+
position: [3], limit: [10]
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 61 62 63 00 00 00 00 00 00 00 |abc....... |
+--------+-------------------------------------------------+----------------+
97
+--------+-------------------- all ------------------------+----------------+
position: [1], limit: [3]
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 61 62 63 00 00 00 00 00 00 00 |abc....... |
+--------+-------------------------------------------------+----------------+
+--------+-------------------- all ------------------------+----------------+
position: [2], limit: [10]
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 62 63 63 00 00 00 00 00 00 00 |bcc....... |
+--------+-------------------------------------------------+----------------+
+--------+-------------------- all ------------------------+----------------+
position: [3], limit: [10]
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 62 63 65 00 00 00 00 00 00 00 |bce....... |
+--------+-------------------------------------------------+----------------+

分配内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.redisc;

import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;

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

public static void main(String[] args) {
System.out.println(ByteBuffer.allocate(16).getClass());
System.out.println(ByteBuffer.allocateDirect(16).getClass());
}
}

输出

1
2
class java.nio.HeapByteBuffer --java 堆内存,读写效率低,垃圾可以回收
class java.nio.DirectByteBuffer -- 直接内存,读写效率高,垃圾不回收,分配的效率低

读写

写入

  • 调用 channelread 方法
    • int readBytes = channel.read(buf);
  • 调用 buffer 自己的 put 方法
    • buf.put((byte)127);

读取

  • 调用 channelwrite 方法
    • int writeBytes = channel.write(buf);
  • 调用 buffer 自己的 get 方法
    • byte b = buf.get();
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
package com.redisc;

import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;

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

public static void main(String[] args) {
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put(new byte[]{'a','b','c','d'});
buffer.flip();

//从头读
buffer.get(new byte[4]); // 会移动 position abcd
buffer.rewind(); //再次把 position 指向 0,又可以重新读取了
buffer.get(); // a position 指向 1
buffer.mark(); // 做标记,记录一下 position 位置,mark = 1
buffer.get(); // b position 指向 2
buffer.reset(); // 将 position 重制到 mark 位置 position = 1
System.out.println((char)buffer.get()); // b
buffer.get(3); // d 但是 position 不会变 get(i) 不改变读索引的位置


}
}

字符串与 bytebuffer 互转

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
package com.redisc;

import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

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

public static void main(String[] args) {
// 字符串转化为 ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(16);
buffer.put("hello".getBytes()); // 还是写模式 position = 5

// Charset
ByteBuffer byteBuffer = StandardCharsets.UTF_8.encode("hello"); // 执行完,已经是读模式了 position = 0

// wrap
ByteBuffer byteBuffer1 = ByteBuffer.wrap("hello".getBytes()); // 执行完直接切换到读模式

// bytebuffer 转为 string
String str1 = StandardCharsets.UTF_8.decode(byteBuffer1).toString(); // 这个需要切换到读模式才能使用

}
}
请我喝杯咖啡吧~