Okio使用篇

Note: okio版本为3.3.0

Okio是一个用于io操作的框架

Okio的出现源于java.io以及java.nio不够简洁,不易使用,学习成本大

Okio解决了上手成本的问题

目前okio已经由kotlin重写,并使用了kotlin multiplatform实现跨平台

这已是Okio的几乎所有类

from doc

image-20230402164721569

Okio组成

ByteString & Buffer

  • ByteString

    String的增强类,其中包含二进制编码,Base64,UTF-8编码,等。

  • Buffer

    byte[]的增强,Buffer的组织不同于byte[]Buffer的数据会形成一个链表结构,一个节点只是类的一部分。

Source & Sink

  • Source
  • Sink

类似于java.io中的InputStreamOutputStream,不同的是Source/Sink类关系更少,方法更少,更简单,并且还提供了Timeout机制,允许使用者自定义超时策略

ByteString

ByteString是String的争抢版,支持编码,摘要计算

1
2
3
4
5
6
7
8
9
10
11
fun main() {

val m = "Hello".toByteArray().toByteString()
println(m.base64())
println(m.sha256().hex())
println(m.base64Url())
println(m.md5().hex())
println(m.sha1().hex())
println(m.sha512().hex())

}

Buffer

与ByteBuffer类似

1
actual class Buffer : BufferedSource, BufferedSink, Cloneable, ByteChannel

image-20230402200510068

image-20230402200541451

Sink

Sink为一个接口

标志性的方法就是write,表明它和OutputStream一样可以输出内容

image-20230402202750615

如下是Okio-JVM的继承关系

image-20230402202954870

Source

image-20230402203105809

Source的实现类和Sink是成对的

image-20230402203209050

Sink/Source使用

Sink/Source的创建很简单

  • FileSystem直接创建
  • 使用扩展函数

image-20230402213950127

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fun fromNet() {

Socket("127.0.0.1", 7899)
.source()
.buffer()
.gzip()

}

fun fromFile() {

val source = FileSystem.SYSTEM
.source("okio/test.txt".toPath())
.buffer()
val arr = ByteArray(1024)

while (!source.exhausted()) {
val len = source.read(arr)
println(String(arr, 0, len))
}
}

timeout

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fun main() {

val source = File("okio/test.txt")
.inputStream()
.buffered()
.source()
.buffer()
.apply {
// 1 nano seconds 以后即超时。
timeout().deadline(1,TimeUnit.NANOSECONDS)
}


val read = source.read(ByteArray(1024))
println(read)

}

输出

Exception in thread “main” java.io.InterruptedIOException: deadline reached
at okio.Timeout.throwIfReached(Timeout.kt:103)
at okio.InputStreamSource.read(JvmOkio.kt:91)
at okio.RealBufferedSource.read(RealBufferedSource.kt:262)
at okio.RealBufferedSource.read(RealBufferedSource.kt:75)
at com.example.okio.TestKt.main(Test.kt:31)
at com.example.okio.TestKt.main(Test.kt)