You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中解析蓝牙传输的CSV ByteArray为字符串数组问题求助

问题解决:解析蓝牙CSV ByteArray为字符串数组

原代码的问题点

  • 数组初始化错误:Kotlin中Array的第二个参数需要是初始化函数,原代码Array<String>(100, "".toString())语法错误,正确写法是Array(100) { "" }。
  • 字符串截取逻辑错误:
    • copyOfRange(j, i-1)是左闭右开区间,会漏掉第i-1位的字符;
    • 直接调用ByteArray.toString()不会把字节数组转成对应字符串,而是返回类似[B@xxxxxxx的对象标识,需要用String构造函数指定区间转字符串。
  • 未兼容末尾无分号的情况(虽然示例末尾有分号,但实际场景可能存在例外)。

修正后的代码方案

方案1:简洁版(转字符串后分割)

这种方式最简便,适合大多数场景:

private fun processMessage(value: ByteArray) {
    // 将ByteArray转成字符串,注意指定编码(需和发送端一致,一般用UTF-8)
    val csvString = String(value, Charsets.UTF_8)
    // 按分号分割,过滤空字符串(处理末尾分号产生的空元素)
    val fields = csvString.split(";").filterNot { it.isEmpty() }.toTypedArray()
    
    // 后续处理fields数组示例
    fields.forEachIndexed { index, field ->
        println("字段$index: $field")
    }
}

方案2:手动遍历版(贴合原有写法)

如果想保留手动遍历的逻辑,修正后的代码如下:

private fun processMessage(value: ByteArray) {
    // 用可变列表存储字段,无需提前预设大小,更灵活
    val fields = mutableListOf<String>()
    var startIndex = 0

    for (i in value.indices) {
        if (value[i] == ';'.toByte()) {
            // 截取从startIndex到i的区间(左闭右开,刚好不包含分号)
            val field = String(value, startIndex, i - startIndex, Charsets.UTF_8)
            fields.add(field)
            startIndex = i + 1
        }
    }

    // 处理最后一段无分号结尾的字节
    if (startIndex < value.size) {
        val field = String(value, startIndex, value.size - startIndex, Charsets.UTF_8)
        fields.add(field)
    }

    // 转成固定大小的字符串数组(按需使用)
    val stringArray = fields.toTypedArray()
    
    // 后续处理示例
    stringArray.forEachIndexed { index, field ->
        println("字段$index: $field")
    }
}

关键说明

  • 转字符串时必须指定字符编码(如Charsets.UTF_8),避免因编码不一致导致乱码。
  • 用MutableList代替固定大小的Array更适配字段数量不固定的场景,最后转成Array只需调用toTypedArray()。

内容的提问来源于stack exchange,提问作者PrinzAkim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 13:14:53