Kotlin ByteArray 和 ByteBuffer 深度解析
1、ByteArray(字节数组)
1.1、基本特性
固定大小的原生字节序列
JVM上对应Java的byte[]
索引访问速度极快(O(1))
1.2、创建方式
// 1. 指定大小初始化
val emptyArray = ByteArray(10)
// 2. 使用字面量
val literalArray = byteArrayOf(0x48, 0x65, 0x6C, 0x6C, 0x6F)
// 3. 从其他类型转换
"Hello".toByteArray(Charsets.UTF_8)1.3、核心操作
val bytes = ByteArray(5)
// 读写操作
bytes[0] = 127 // 写入
val b = bytes[1] // 读取
// 常用扩展函数
bytes.fill(0) // 填充
bytes.copyInto(destination) // 复制
bytes.sliceArray(1..3) // 切片1.4、二进制数据处理示例
// 合并两个ByteArray
fun combineArrays(a1: ByteArray, a2: ByteArray): ByteArray {
return a1 + a2 // 使用+运算符拼接
}
// HEX字符串转换
fun ByteArray.toHex(): String = joinToString("") { "%02x".format(it) }
// Base64编码/解码
Base64.getEncoder().encode(bytes)
Base64.getDecoder().decode(base64Str)2、ByteBuffer(字节缓冲区)
2.1、设计目的
提供结构化二进制数据读写能力
支持高低级混合操作
内置字节序(endianness)控制
2.2、关键特性对比
特性 ByteArrayByteBuffer
存储结构 连续内存可基于堆/直接内存
访问模式 随机访问游标(position)控制访问
字节序 平台默认可配置(LITTLE/BIG_ENDIAN)
数据类型支持仅byte 多类型(short/int/long等)
2.3、创建实例
// 1. 分配堆内缓冲区
val heapBuffer = ByteBuffer.allocate(1024)
// 2. 分配直接内存缓冲区(零拷贝I/O)
val directBuffer = ByteBuffer.allocateDirect(1024)
// 3. 包装现有数组
val wrappedBuffer = ByteBuffer.wrap(byteArray)2.4、核心操作方法
写操作模式
buffer.put(0x41) // 写入单个字节
buffer.put("text".toByteArray()) // 写入字节数组
buffer.putShort(32767) // 写入2字节short
buffer.putInt(0xCAFEBABE) // 写入4字节int
buffer.putDouble(Math.PI) // 写入8字节double读操作模式
buffer.flip() // 切换为读模式
val byteVal = buffer.get() // 读取1字节
val shortVal = buffer.short // 读取2字节
val intVal = buffer.int // 读取4字节
val remainingBytes = ByteArray(buffer.remaining())
buffer.get(remainingBytes) // 读取剩余全部字节视图操作
// 创建不同数据类型的视图
val intBuffer = buffer.asIntBuffer()
val charBuffer = buffer.asCharBuffer()
// 修改字节序
buffer.order(ByteOrder.LITTLE_ENDIAN)协议封装示例
fun createPacket(id: Int, payload: ByteArray): ByteArray {
return ByteBuffer.allocate(4 + payload.size).run {
putInt(id)
put(payload)
array()
}
}性能敏感型IO处理
fileChannel.read(byteBuffer) // 零拷贝文件读取
while (byteBuffer.hasRemaining()) {
processData(byteBuffer.getInt())
}3、应用场景选择指南
优先使用ByteArray:
简单的字节序列存储
不需要复杂的位置管理
与其他Kotlin API交互
选用ByteBuffer的情况:
需要处理多种原始数据类型
涉及NIO通道操作(FileChannel/SocketChannel)
要求精确控制字节顺序
高性能二进制协议解析
4、特别注意事项
ByteBuffer状态机:创建 → [写入] → flip() → [读取] → clear()/compact() → [写入]
直接缓冲区的陷阱:分配成本较高但IO效率更好。不受GC管理,可能造成本地内存泄漏
线程安全性:两者均非线程安全。多线程访问需要外部同步
fun ByteBuffer.getString(length: Int): String {
val bytes = ByteArray(length)
this.get(bytes)
return String(bytes, Charsets.UTF_8)
}掌握这两种数据结构可以高效处理各种二进制场景,特别是在网络协议、文件格式编解码等领域非常有用。

