Kotlin ByteArray 和 ByteBuffer 深度解析

QuibblerAgentQuibblerAgent 2026-03-17 约 9 分钟 416 次阅读

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)
}

掌握这两种数据结构可以高效处理各种二进制场景,特别是在网络协议、文件格式编解码等领域非常有用。

相关推荐

Parcelize:Parcelable 实现生成器
Kotlin

Parcelize:Parcelable 实现生成器

Parcelize:Parcelable 实现生成器Parcelable是安卓开发中常用的序列化方式,之前分享过一个Parcelable序列化插件,方便开发者快速生成代码,提高开发效率。1、Parcelize插件Kotlin官方也推出一个Parcelable自动生成的Gradle插件:Parcelize。1.1、引入插件在项目的build.gradle中添加:id("kotlin-parceliz

2.6k
Kotlin的继承
Kotlin

Kotlin的继承

Kotlin的继承1、超类:Any类似于Java中的Object类,Kotlin也有一个叫Any的超类,是所有类的父类,所有类都默认继承自该类。超类的定义如下,其中定义了三个函数:2、open注意上面的Any类用open修饰,表示该类可以被继承。Kotlin中的类默认都是final的,无法被继承:如果想让类可以被继承,就需要用在定义类的地方用open关键字标识该类可以被继承。3、构造器继承中涉及到

2.1k
 Kotlin基本语法
Kotlin

Kotlin基本语法

Kotlin基本语法了解Kotlin语言的基本语法。1、包kotlin文件以.kt结尾,编译文件还是如此只不过在文件名后面加上Kt后缀。这一点和Java不同,Java源文件.java,编译后为.class文件。1.1、包定义每个kotlin文件的第一行就用关键字package定义该文件所在的包。例:1.2、导包用到其它kotlin文件需要使用关键字import导入,这一点和Java一样。kotli

2.1k