基本概念

Okio java.io
ByteString String
Buffer ByteArray
Source InputStream
Sink OutputStream
Segment
SegmentPool

ByteString

虽然 okio.ByteString 对标的是 java.lang.String,但是它操作的对象却是 String 内部的 ByteArray,相较于 String 的 字符数据 更贴近于 字节数据 的概念

类别 API
字符编码(charset) utf8()
string(charset)
消息摘要(message digest) md5() 128-bit
hmacSha1(key) 160-bit, hmacSha256(key) 256-bit, hmacSha512(key) 512-bit <br> hmac 是额外添加了一个秘钥作为影响因子的 sha
sha1() 160-bit, sha256() 256-bit, sha512() 512-bit
digest(algorithm)
基于字节的匹配和查找(而不是字符) rangeEquals(offset, other ByteString/ByteArray, otherOffset, byteCount)
startsWith(ByteString/ByteArray)
endsWith(ByteString/ByteArray)
indexOf(other ByteString/ByteArray, fromIndex)
lastIndexOf(other ByteString/ByteArray, fromIndex)
其他 hex()
toAsciiLowercase()
toAsciiUppercase()

Buffer

API 描述
read/write 读写各种类型的数据类型
copy()/clone() 返回一个共享数据的 Buffer <br> 这个就比较有意思了,我们知道 Buffer 用 Segment 对数据进行分片管理(类似于内存的分页),这里并没有真正将数据拷贝一份到另一个 Buffer(要节约内存嘛),而是让另一个 Buffer 里的 Segment 与当前 Buffer 里的 Segment 共享用一个 ByteArray <br> 新的 Segment 可以有自己的 pos 和 limit,可以读但不能写(Segment.owner == false,写入的数据会放到新创建的/自己的 Segment 里去),不然会把别人的数据搞乱,当然 Segment 的持有者是可以写的(Segment.owner == true) <br> 共享了数据的 Segment 不能被 SegmentPool 回收(因为可能别人还在用,而且内部没有计算器指示被多少人持有),它的 Segment.share == true
copyTo(Buffer) 使另一个 Buffer 与当前 Buffer 共享某一段数据
peek() 返回一个可以重复读的 Source(一般的 Source 跟 InputStream 一样是单向/流式的,不能重复读),但是这个 Buffer 作为 Source 的 backend,已读的数据 Source 也是无法读取的
snapshot(byteCount) 返回一个 ByteString(上面说过 Okio ByteString 对标 java.lang.String),特别的是它与 Buffer 是共享底层 ByteArray 的(不是共享 Segment,但会使 Segment.shared 置真) <br> ByteString 是不可变的所以它不会修改共享的 ByteArray
skip(byteCount) 跳过 byteCount 字节的数据,使读指针 pos 前进 byteCount 位(已读完的 Segment 将被回收)
inputStream() 把 Buffer 作为输入流的源
outputStream() 把 Buffer 作为输出流的目的地
copyTo(OutputStream) 将 Buffer 里的数据拷贝一份到 OutputStream,不移动 Segment.pos(也即不会释放已读数据)
writeTo(OutputStream) 将 Buffer 里的数据写入到 OutputStream,会移动 Segment.pos
readFrom(InputStream) 将 InputStream 里的数据读到 Buffer 里

SegmentPool