IO系列 | 一文掌握OKHTTP中的OKIO为什么这么OK

前言

本篇是 IO系列 的第4篇,前三篇文章中,我们已经对JAVA经典IO设计、JAVA-NIO内容、操作系统IO架构基础概念、Zero-Copy做了较为系统的回顾。

而绝大部分Android应用中都会涉及到网络模块,RetrofitOkhttp 几乎是必用的框架, Okio 作为 Okhttp 中的重要模块,原先用于处理网络模块中的IO问题,随着其项目发展,Okio也开始面向其他问题。

这一篇,我们一同对OKIO做一次系统的梳理,搞明白OKIO为什么OK,做到在面试中自如的吹牛批、在日常工作中灵活使用。

编者按:面试吹牛批需要把握尺度,避免远超岗位预期,导致浪费时间

因文章篇幅较长,可结合内容导图阅读:

okio.png

okio的主旨与架构

在OKIO项目的 wiki 中,对其主旨有如下介绍:

Okio is a library that complements java.io and java.nio to make it much easier to access, store, and process your data. It started as a component of OkHttp, the capable HTTP client included in Android. It’s well-exercised and ready to solve new problems.

简单直译为中文如下:

Okio是一个类库,对 java.iojava.nio 进行了补充,使得访问、存储和处理数据变得更加容易。它最初是OkHttp的一个组件,OkHttp是安卓中的一个功能强大的HTTP客户端。它非常健壮,可以解决新问题。

简言之:为了更简单的访问、存储、处理数据,基于 java.iojava.nio 进行了功能补充

wiki中,简单介绍了设计中的几个重点角色:

  • ByteStrings and Buffers
  • Sources and Sinks

分层架构中相对扁平、简单:在应用和Java IO 之间增加了一层,即OKIO本身,包含 数据封装输入输出超时机制

体现在类图上还是比较复杂的:

图片.png

在库内部,ByteStrings 的使用不多,对 Buffer 数据包装后为上层应用服务,单独拎出。

KtsampleOkioDiagramReport2.png

信息噪声比较多,去掉功能装饰的实现类后较为精简:

KtsampleOkioDiagramReport.png

与Java的输入输出的对比

Java经典IO中的输入输出定义为Stream,在 系列文章 中进行了介绍。字符流类似,图略

在JDK的IO框架中,使用装饰模式建立了规模庞大、功能丰富的输入输出流。从OKIO的主旨出发,不难理解其设计者希望类库尽可能简单、易扩展、内建部分功能足够完善。因此,OKIO会适当的另起炉灶,不会全面的使用JDK中的Stream。

OKIO中使用了自定义的输入、输出,即 SourceSink ,注意淡黄色、淡粉色部分:

Sink 在计算机领域有特定含义:指程序或者线程,可以接收数据,并且可以处理或者发送这些数据

KtsampleOkioDiagramReport.png

差异点

在wiki中提到如下内容:

An elegant part of the java.io design is how streams can be layered for transformations like encryption and compression. Okio includes its own stream types called Source and Sink that work like InputStream and OutputStream, but with some key differences:

  • Timeouts.
  • Easy to implement.
  • Easy to use.
  • No artificial distinction between byte streams and char streams.
  • Easy to test.

简单翻译下, Java IO的设计中有一处非常优雅:可以调整流的分层包装以实现加密、压缩等转换。OKIO包含自有的流类型 SourceSink,与Java的 InputStream OutputStream 功能类似,但是有几点关键的不同:

  • 超时机制
  • 更容易实现
  • 更容易使用
  • 字节流、字符流之间没有人为的差异
  • 更容易测试

从输入方面看

在JDK中,InputStream 使用多种层(以及复合层)处理种类繁多的各类数据

  • DataInputStream 用于处理基础数据类型
  • BufferedInputStream 处理缓冲
  • InputStreamReader 处理文本字符串

而OKIO在这些层之上建立了 BufferedSource,Source避免了一些无法实现 available() 方法的困境, 转而由调用者指定它们需要的byte个数

在实现一个Source时,不必操心 read() 方法,它难以有效实现且需从257种值中返回一个 ,注:null & [0x00,0xFF]

从输出方面看

类似的,在JDK中 OutputStream 使用多种层(以及复合层)处理种类繁多的各类数据,而Sink也非常容易采用分层设计

相同点

  • SourceSink 的功能与 InputStreamOutputStreamReaderWriter 相同
  • 使用时可以通过装饰追加功能

对于功能相同,wiki中提到如下内容:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值