Charset

预计阅读时间:3分钟

字符集是负责对字符进行序列化和反序列化的类. 它模仿Java java.nio.charset.Charset类,在.NET中等效的是Encoding类.

字符集的一些示例可以是UTF-8ASCIIutf-8LATIN1 )或SHIFT_JIS等.

Instantiating a Charset

kotlinx-io有一个名为Charsets的对象,其中包含一些常用的字符集(目前仅UTF-8 ):

val charset = Charsets.UTF_8

也可以从其名称构造一个字符集:

val charset = Charset.forName("utf-8")

Encoding and decoding Strings

使用字符集对字符串进行编码/解码的最简单方法是使用StringByteArray可用的扩展方法.

例如,如果我们有一个表示UTF-8编码字符串的ByteArray ,则可以:

val utf8Encoded: ByteArray = byteArrayOf(0xE4.toByte(), 0xBB.toByte(), 0x8A.toByte(), 0xE6.toByte(), 0x97.toByte(), 0xA5.toByte(), 0xE3.toByte(), 0x81.toByte(), 0xAF.toByte(), 0xEF.toByte(), 0xBC.toByte(), 0x81.toByte())
val string = utf8Encoded.toString(Charsets.UTF_8)

您也可以使用扩展构造函数:

val string = String(utf8Encoded, charset = Charsets.UTF_8)
val substring = String(utf8Encoded, 0, 10, charset = Charsets.UTF_8)

String ,您可以生成一个以特定字符集表示它的ByteArray:

val string = "今日は!"
val utf8Encoded = string.toByteArray(Charsets.UTF_8)

Performance-aware API

为了能够减少复制,对象和内存的重用并减少垃圾回收,Charset API提供了一种创建编码器和解码器的方法,这些编码器和解码器提供了从CharSequence编码到Output API,反之亦然.

为了对String进行编码而不将其切片为Output ,您可以:

val output: Output
val charset = Charsets.UTF_8
val charsetEncoder = charset.newEncoder() 
charsetEncoder.encode("HELLO", 1, 2, output)

Further details about Charsets

一些字符集将字符表示为单字节,其他字符集表示每个字符具有几个固定字节的字符,而其他字符集则是可变的. 并非所有字符集都可以代表整个Unicode字符集.

使用最广泛的字符集是UTF-8,它可以将大多数7位ASCII字符表示为单个字节,但可以表示整个Unicode字符集. 通过用可变长度的字节进行编码,获取表示为UTF-8的String的长度需要对整个内容进行解码,因此需要线性时间来进行查找,切片和获取长度.

JavaScript公开具有32位CodePoints的字符串,而Java和Native则使用替代对获得更高的值公开16位字符.

目前,kotlinx-io仅实现UTF_8 ,但允许通过扩展Charset类来添加自定义字符集.

Exposed API

object Charsets {
    val UTF_8: Charset
}

class Charset {
    companion object {
        fun forName(name: String): Charset
    }

    val name: String

    fun newEncoder(): CharsetEncoder
    fun newDecoder(): CharsetDecoder
}

class CharsetEncoder {
    val charset: Charset
    fun encode(input: CharSequence, fromIndex: Int, toIndex: Int, dst: Output)
    fun encodeToByteArray(input: CharSequence, fromIndex: Int = 0, toIndex: Int = input.length): ByteArray
    fun encodeUTF8(input: ByteReadPacket, dst: Output) // Return type. Why UTF8 ??
    fun encode(input: CharSequence, fromIndex: Int = 0, toIndex: Int = input.length) // Return type. Why UTF8 ??
    fun encodeUTF8(input: ByteReadPacket) // Return type. Why UTF8 ??
}

class CharsetDecoder {
    val charset: Charset
    fun decode(input: Input, max: Int = Int.MAX_VALUE): String
    fun decode(input: Input, dst: Appendable, max: Int): Int
    fun decodeExactBytes(input: Input, inputLength: Int): String
}

class MalformedInputException(message: String) : Throwable

// Missing:
//   - String.toByteArray(charset): ByteArray
//   - ByteArray.toString(charset): String
// Missing registering new charsets available using Charset.forName?

by  ICOPY.SITE