☠博主专栏 : <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关>
♝博主的话 : 搬的每块砖,皆为峰峦之基;公众号搜索「码到三十五」关注这个爱发技术干货的coder,一起筑基
目录
- 引言
- 一、ByteBuffer类概述
- 二、ByteBuffer的属性
- 2.1 Capacity
- 2.2 Limit
- 2.3 Position
- 2.4 Mark
- 2.5 使用
- 三、基本操作
- 四、ByteBuffer的用法
- 总结
引言
Java NIO(New I/O)是Java中处理输入/输出操作的一种新模型,它提供了非阻塞I/O操作,允许程序在一个线程中管理多个I/O操作,提高了系统的并发处理能力和性能表现。在Java NIO中,ByteBuffer类是一个重要的组成部分,用于处理字节数据,提供了高效、灵活的字节数据处理方式。
一、ByteBuffer类概述
ByteBuffer是Java NIO包中的一个类,它实现了Buffer接口,是处理字节数据的基础类。ByteBuffer类提供了多种方法,用于读取和写入字节数据,以及管理缓冲区的状态。ByteBuffer类支持多种数据类型,包括字节、字符、短整型、整型、长整型、浮点型和双精度浮点型等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RvCPU9rd-1721094061284)(https://i-blog.csdnimg.cn/direct/784e1960ff9842069e2e6f2f0fc34912.jpeg#pic_center)]
ByteBuffer内部使用一个字节数组(byte[])来存储数据,通过操作数组中的索引位置来实现数据的读写。ByteBuffer类提供了多种方法,用于读取和写入字节数据,以及管理缓冲区的状态。
二、ByteBuffer的属性
2.1 Capacity
概念:表示Buffer的最大容量,即在创建Buffer时分配的内存空间大小。它是Buffer的根本限制,不能被修改。
作用:Capacity定义了Buffer可以容纳的最大数据量,它决定了Buffer的底层数组的大小。
2.2 Limit
定义:Limit是Buffer中第一个不应该被读取或写入的元素的索引。
影响:Limit限制了Buffer中可读或可写的元素的范围。在写模式(put操作)下,limit是写入数据的结束位置;在读模式(get操作)下,limit是读取数据的结束位置。
2.3 Position
角色:Position表示下一个应该被读取或写入的元素的索引。
读写操作:在写模式(put操作)下,position会随着数据的写入而自动增加;在读模式(get操作)下,position会随着数据的读取而自动增加。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-chnr29ds-1721094061287)(https://i-blog.csdnimg.cn/direct/f55e583778494357a56f1e70d7508878.jpeg#pic_center)]
2.4 Mark
设定:Mark是用于标记position当前位置的一个指针。可以通过调用mark()方法来设定。
复位:如果需要回到之前标记的位置,可以调用reset()方法。reset()方法会将position设置为mark所标记的位置。
2.5 使用
以下是一个使用ByteBuffer的代码,展示了Capacity、Limit和Position的变化:
import java.nio.ByteBuffer;
public class ByteBufferDemo {
public static void main(String[] args) {
// 创建一个初始容量为10的ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(10);
// 输出初始值
System.out.println("Initial values:");
System.out.println("Capacity: " + buffer.capacity());
System.out.println("Limit: " + buffer.limit());
System.out.println("Position: " + buffer.position());
// 写入数据
for (int i = 0; i < 5; i++) {
buffer.put((byte) i);
}
// 输出写入数据后的值
System.out.println("After writing data:");
System.out.println("Capacity: " + buffer.capacity());
System.out.println("Limit: " + buffer.limit());
System.out.println("Position: " + buffer.position());
// 切换到读模式
buffer.flip();
// 输出切换模式后的值
System.out.println("After flipping:");
System.out.println("Capacity: " + buffer.capacity());
System.out.println("Limit: " + buffer.limit());
System.out.println("Position: " + buffer.position());
// 读取数据
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get() + " ");
}
// 输出读取数据后的值
System.out.println("After reading data:");
System.out.println("Capacity: " + buffer.capacity());
System.out.println("Limit: " + buffer.limit());
System.out.println("Position: " + buffer.position());
}
}
创建了一个初始容量为10的ByteBuffer,并写入5个字节的数据。在写入数据后,我们调用flip()方法切换到读模式,并读取之前写入的数据。在整个过程中,我们观察了Capacity、Limit和Position的变化。代码展示了ByteBuffer的基本使用,包括数据的写入、读取以及Buffer状态的切换。通过理解Capacity、Limit和Position的变化,我们可以更好地使用ByteBuffer进行数据的读写操作。
三、基本操作
- 分配空间:通过
ByteBuffer.allocate(int capacity)
方法分配指定容量的ByteBuffer。 - 包装现有数组:通过
ByteBuffer.wrap(byte[] array)
方法使用指定的字节数组创建ByteBuffer。 - 读取和写入数据:使用
put(byte b)
方法向缓冲区中写入数据,使用get()
方法从缓冲区中读取数据。 - 翻转:通过
flip()
方法将缓冲区从写模式切换到读模式。 - 清除:通过
clear()
方法清空缓冲区,准备再次写入数据。 - 压缩:通过
compact()
方法将未读取的数据压缩到缓冲区的起始位置。
四、ByteBuffer的用法
下面是使用ByteBuffer读取和写入数据的基本代码:
import java.nio.ByteBuffer;
public class ByteBufferDemo {
public static void main(String[] args) {
// 分配一个容量为10的ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(10);
// 写入数据
buffer.put((byte)'a');
buffer.put((byte)'b');
buffer.put((byte)'c');
// 切换为读模式
buffer.flip();
// 读取数据
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
// 清空缓冲区
buffer.clear();
}
}
我们首先分配了一个容量为10的ByteBuffer,然后向缓冲区中写入了3个字节的数据(‘a’,‘b’,‘c’)。然后,通过调用flip()方法将缓冲区从写模式切换到读模式,并使用get()方法读取缓冲区中的数据。最后,通过调用clear()方法清空缓冲区,准备再次写入数据。
总结
ByteBuffer类是Java NIO中处理字节数据的重要工具之一,提供了高效、灵活的字节数据处理方式。通过ByteBuffer类,我们可以进行数据的读取和写入操作,管理缓冲区的状态,以及处理不同类型的字节数据。在实际应用中,ByteBuffer类常用于文件I/O操作、网络通信、数据打包与解包等场景。