Java NIO 编程之 ByteBuffer 基础(ByteBuffer 概述、创建 ByteBuffer、基础读写操作、核心属性与模式切换)

一、ByteBuffer 概述

  • ByteBuffer 是 Java NIO 中用于高效处理二进制数据的类,它提供了比传统 IO 更灵活的数据操作方式,它有如下特点
  1. 固定容量:创建时指定大小,不可动态扩展

  2. 双指针机制:通过 position 和 limit 控制读写位置

  3. 直接内存支持:可分配堆外内存减少拷贝开销

  4. 视图缓冲:可生成只读、读写视图

  5. 字节序控制:支持大端和小端


二、创建 ByteBuffer

1、基本介绍
  1. 堆内存分配
static ByteBuffer allocate(int capacity)
  1. 直接内存分配
static ByteBuffer allocateDirect(int capacity)
  1. 包装现有数组
static ByteBuffer wrap(byte[] array)
  1. 包装数组子范围
static ByteBuffer wrap(byte[] array, int offset, int length)
2、演示
  1. 堆内存分配,分配 100 字节的堆内存缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(100);
  1. 直接内存分配,分配 100 字节的直接内存缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(100);
  1. 包装现有数组
byte[] byteArray = new byte[100];
ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
  1. 包装数组子范围,偏移 10,长度 50
byte[] byteArray = new byte[100];
ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray, 10, 50);
3、堆内存缓冲区与直接内存缓冲区
特性堆内存缓冲区直接内存缓冲区
内存位置JVM 堆内存堆外内存
分配速度较快较慢
IO 效率需要拷贝零拷贝
垃圾回收通过 GC 管理通过 Cleaner 机制回收
适用场景短期使用、小数据量长期使用、大数据量、高频IO

三、基础读写操作

1、基本介绍
  1. 读取数据
ByteBuffer put(byte b)
  1. 写入数据
byte get()
2、演示
  1. 读取数据
ByteBuffer byteBuffer = ByteBuffer.wrap("Hello World".getBytes());

while (byteBuffer.hasRemaining()) {
    System.out.println((char) byteBuffer.get());
}
# 输出结果

H
e
l
l
o
  1. 写入数据
ByteBuffer byteBuffer = ByteBuffer.wrap("Hello World".getBytes());

while (byteBuffer.hasRemaining()) {
    System.out.println((char) byteBuffer.get());
}
# 输出结果

H
e
l
l
o
 
W
o
r
l
d

四、核心属性与模式切换

1、基本介绍
  1. 核心属性
属性获取方法说明
capacityint capacity()缓冲区总容量,创建后不可变
positionint position()下一个要读写的位置,初始为 0
limitint limit()可读写数据的终点位置,初始等于 capacity
mark无直接获取方法标记位置,可通过 reset 方法返回到此位置
  1. 模式切换方法
方法作用
ByteBuffer flip()写切换到读模式:limit = position, position = 0
clear读切换到写模式:limit = capacity, position=0
rewind重读:position = 0,不改变 limit
compact压缩:将未读数据移到开头,position = 剩余数据量
2、演示
  1. flip 方法
ByteBuffer buf = ByteBuffer.allocate(10);
buf.put("abc".getBytes());

System.out.println("写模式: pos=" + buf.position() + ", limit=" + buf.limit());

buf.flip();

System.out.println("读模式: pos=" + buf.position() + ", limit=" + buf.limit());
# 输出结果

写模式: pos=3, limit=10
读模式: pos=0, limit=3
  1. clear 方法
ByteBuffer buf = ByteBuffer.allocate(10);
buf.put("abc".getBytes());

System.out.println("写模式: pos=" + buf.position() + ", limit=" + buf.limit());

buf.flip();

System.out.println("读模式: pos=" + buf.position() + ", limit=" + buf.limit());

buf.clear();

System.out.println("写模式: pos=" + buf.position() + ", limit=" + buf.limit());
# 输出结果

写模式: pos=3, limit=10
读模式: pos=0, limit=3
写模式: pos=0, limit=10
  1. rewind 方法
ByteBuffer buf = ByteBuffer.allocate(10);
buf.put("xyz".getBytes());

buf.flip();

System.out.println("第一次读取: " + (char) buf.get());
System.out.println("当前 pos: " + buf.position());

buf.rewind();

System.out.println("重读: " + (char) buf.get());
System.out.println("当前 pos: " + buf.position());
# 输出结果

第一次读取: x
当前 pos: 1
重读: x
当前 pos: 1
  1. compact 方法
ByteBuffer buf = ByteBuffer.allocate(10);
buf.put("123456".getBytes());

buf.flip();

System.out.println("读取数据: " + (char) buf.get());
System.out.println("未读数据: " + (char) buf.get());

System.out.println("压缩前: pos=" + buf.position() + ", 剩余数据=" + buf.remaining());

buf.compact();

System.out.println("压缩后: pos=" + buf.position() + ", 剩余空间=" + buf.remaining());
# 输出结果

读取数据: 1
未读数据: 2
压缩前: pos=2, 剩余数据=4
压缩后: pos=4, 剩余空间=6
  • mark 方法与 reset 方法
ByteBuffer buf = ByteBuffer.allocate(10);
buf.put("123456".getBytes());

buf.flip();

System.out.println("读取数据: " + (char) buf.get());
System.out.println("未读数据: " + (char) buf.get());

buf.mark();

System.out.println("读取数据: " + (char) buf.get());
System.out.println("未读数据: " + (char) buf.get());

buf.reset();

System.out.println("重置后");

System.out.println("读取数据: " + (char) buf.get());
System.out.println("未读数据: " + (char) buf.get());
# 输出结果

读取数据: 1
未读数据: 2
读取数据: 3
未读数据: 4
重置后
读取数据: 3
未读数据: 4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值