Kotlin中除String()构造方法外ByteArray转字符串方法及UTF-8转码乱码原因
解答
UTF-8转码出现乱码的原因
UTF-8编码有严格的格式校验规则:
- 单字节字符的取值范围为
0x00~0x7F(对应十进制0~127),最高位为0 - 多字节字符的首字节高位连续1的数量代表该字符占用的字节数,后续每个字节必须以
10开头 - 当解码器遇到不符合规则的字节时,会默认用替换字符
�填充,表现为乱码
你提供的ByteArray中存在大量超出0~127范围的有符号负数字节,且字节序列不符合UTF-8的编码规则,本质是该ByteArray本身不是由UTF-8编码字符串生成的字节序列,强行用UTF-8解码自然无法得到正常文本。
Kotlin中ByteArray转字符串的其他可选方式
- 指定对应原始编码解码:如果可以确认ByteArray生成时用的编码(比如GBK、UTF-16、ISO-8859-1等),替换编码参数即可,示例:
// 示例为GBK编码解码,替换为ByteArray对应的原始编码即可 val result = String(byteArray, Charset.forName("GBK")) - 使用Charset的decode方法:适合需要配合ByteBuffer操作的场景,逻辑和String构造方法一致:
val result = Charsets.UTF_8.decode(ByteBuffer.wrap(byteArray)).toString() - 转十六进制字符串:如果ByteArray是二进制数据(比如加密结果、文件片段),不需要转成自然语言文本,可以转成十六进制字符串,不会出现乱码:
// Kotlin 1.9及以上版本内置方法 val hexStr = byteArray.toHexString() // 低版本兼容实现 fun ByteArray.toHex() = joinToString("") { "%02x".format(it) } - 转Base64字符串:如果需要把二进制ByteArray转成可安全传输、存储的ASCII字符串,使用Base64编码:
import java.util.Base64 val base64Str = Base64.getEncoder().encodeToString(byteArray)
注:如果需要得到可阅读的自然语言文本,必须先确认ByteArray的原始编码,否则任意解码方式都会出现乱码。
内容的提问来源于stack exchange,提问作者Hally
相关产品推荐
相关产品推荐

