在 OkHttp 的源码中,我们经常能看到 Okio 的身影,这篇文章,我们把Okio拿出来进行一个详细的介绍学习。

  • 输入输出的概念简述
  • Okio 简介
  • 工程中引入 Okio
  • API 简介及使用介绍

一、输入输出

在正式介绍 Okio 之前,让我们先回忆一下输入/输出流的概念。

  • 输入流:外设——>内存

    将数据从各种外设(如键盘、文件、网络、数据库等)读取到内存中;

  • 输出流:内存——>外设

    与输入流相反,是将内存数据写入到各种外设(如文件、网络、数据库、显示器等);

二、Okio简介

Okio最初是作为OkHttp的一个组件出现,是 OkHttp 实现HTTP协议数据构建、解析中使用到的底层 IO 库。其相比于传统的 java.io 和 java.nio ,其在文件网络等数据读写操作更加便捷、高效

Okio 的设计思想是将数据的读写操作封装为一个统一的接口,即 SourceSink,其中 输入为Source,输出为Sink

  • Okio 还提供了 BufferByteString 用于封装和操作字节数据,提高数据读写的效率。
  • 同时,Okio 还提供了一些工具方法,例如从 InputStreamOutputStream 中创建 BufferedSourceBufferedSink 等。

三、引入Okio

Okio官方API地址为:

https://square.github.io/okio/

Okio Github开源地址为:

https://github.com/square/okio

使用 Okio 时,我们可以查阅官方最新版本,并通过如下方式引入Okio:

implementation("com.squareup.okio:okio:3.2.0")

四、API 简介及使用

  • Buffer 简介及API使用介绍
  • ByteString 简介及API使用介绍
  • Source 和 Sink 使用介绍

4.1 Buffer

Buffer一个大小可变的字节缓冲区,在Okio中BufferBufferedSourceBufferedSink的接口实现类,用户实现字节数据的缓冲与读写。

官方API描述如下:

  • Buffer可以像Arraylist一样,不需要预先设置缓冲区的大小,而是随着数据的增加自动扩充缓冲区大小
  • Buffer由很多的Segment片段构成,每个Segment中维护一个字节数组
  • Buffer中以链表的形式来管理Segment,当使用Buffer进行缓冲区字节数据移动时,其只改变Segment字节数组的所有权,从而提高字节数组的移动效率。

okio.Buffer字节缓冲区的使用方式举例如下:

import okio.Buffer;

Buffer buffer = new Buffer();
// 向缓冲区写入数据
buffer.writeUtf8("key");
buffer.writeByte('=');
buffer.writeUtf8("value"); // 缓冲区字节大小
int byteCount = buffer.size(); // 读取换区中的全部字节数据
byte[] byteArray = buffer.readByteArray();
// 以Utf8编码的形式输出所有字符串
String result = buffer.readUtf8(); // 清空缓冲区
buffer.clear();

4.2 ByteString

ByteString 中维护了大小不可变的字节数组,其可以对存入该字节数组的数据进行base64utf8md5sha256等字符串的编解码操作。

ByteString 更像是一个工具类,在Okio中其重要应用场景也是在网络传输中对数据进行编码和解码工作

官方API描述如下:

其部分静态方法和公有方法如下图所示:

okio.ByteString的使用方式举例如下:

import okio.ByteString;

// utf8编码
ByteString byteString = ByteString.encodeUtf8("hello");
// HEX
ByteString byteString = ByteString.decodeHex("hello");
// 输出utf8字符串
String result = byteString.utf8();

4.3 Source 和 Sink

Source 和 Sink 在前文中提到过输入为Source,输出为Sink。在 Okio 中,SourceSink 用于读取写入数据的抽象类,其提供了一组标准的IO读写方法,可以方便地进行数据的读写操作。

// Okio源码:输入流 Source
// Source 接口类,最主要的方法是 read
public interface Source extends Closeable {
// 读字节数据
long read(Buffer var1, long var2) throws IOException;
// timeout
Timeout timeout();
void close() throws IOException;
}
// Okio源码:输出流 Sink
// Sink 接口类,最主要的方法是 write
public interface Sink extends Closeable, Flushable {
// 写字节数据
void write(Buffer var1, long var2) throws IOException;
void flush() throws IOException;
Timeout timeout();
void close() throws IOException;
}

在把前文已经展示过的Okio结构图拿出来:

  • Source的最终实现类是RealBufferedSource
  • Sink的最终实现类是RealBufferedSink

使用 okio.Source 从文件中读取数据,代码举例如下:

// 使用 Source 从文件中读取数据
public static void readLines(File file) throws IOException {
// 输入流
Source fileSource = Okio.source(file);
// 构建 BufferedSource
RealBufferedSource bufferedSource = Okio.buffer(fileSource);
// 循环读取
while (true) {
// 读取行数据
String line = bufferedSource.readUtf8Line();
if (line == null) {
break;
}
}
}

使用 okio.Sink 向文件中写入数据,代码举例如下:

// 使用 Sink 向文件中写入数据
public static void writeToFile(File file) throws IOException {
// 创建输出流
Sink fileSink = Okio.sink(file);
// 构造 BufferedSink
RealBufferedSink bufferedSink = Okio.buffer(fileSink);
// 向文件中写入数据
bufferedSink.writeUtf8("Hello");
bufferedSink.writeUtf8("\n");
bufferedSink.writeAll(Okio.source(new File("my.txt")));
}

五、参考

Okio API:

https://square.github.io/okio/

Okio Github:

https://github.com/square/okio

Java流:

http://c.biancheng.net/view/1119.html

= THE END =

文章首发于公众号”CODING技术小馆“,如果文章对您有帮助,欢迎关注我的公众号。

一文详解 Okio 输入输出流的更多相关文章

  1. 一文详解Hexo+Github小白建站

    作者:玩世不恭的Coder时间:2020-03-08说明:本文为原创文章,未经允许不可转载,转载前请联系作者 一文详解Hexo+Github小白建站 前言 GitHub是一个面向开源及私有软件项目的托 ...

  2. 一文详解 Linux 系统常用监控工一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)具(top,htop,iotop,iftop)

    一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)     概 述 本文主要记录一下 Linux 系统上一些常用的系统监控工具,非常好用.正所谓磨刀不误砍柴工,花点时间 ...

  3. StreamingContext详解,输入DStream和Reveiver详解

    StreamingContext详解,输入DStream和Reveiver详解 一.StreamingContext详解 1.1两种创建StreamingContext的方式 1.2SteamingC ...

  4. 小甲鱼PE详解之输入表(导出表)详解(PE详解09)

    小甲鱼PE详解之输出表(导出表)详解(PE详解09) 当PE 文件被执行的时候,Windows 加载器将文件装入内存并将导入表(Export Table) 登记的动态链接库(一般是DLL 格式)文件一 ...

  5. 一文详解 OpenGL ES 3.x 渲染管线

    OpenGL ES 构建的三维空间,其中的三维实体由许多的三角形拼接构成.如下图左侧所示的三维实体圆锥,其由许多三角形按照一定规律拼接构成.而组成圆锥的每一个三角形,其任意一个顶点由三维空间中 x.y ...

  6. 一文详解 WebSocket 网络协议

    WebSocket 协议运行在TCP协议之上,与Http协议同属于应用层网络数据传输协议.WebSocket相比于Http协议最大的特点是:允许服务端主动向客户端推送数据(从而解决Http 1.1协议 ...

  7. 一文详解 Linux Crontab 调度任务

    最近接到这样一个任务: 定期(每天.每月)向"特定服务器"传输"软件服务"的运营数据,因此这里涉及到一个定时任务,计划使用Python语言添加Crontab依赖 ...

  8. 1.3w字,一文详解死锁!

    死锁(Dead Lock)指的是两个或两个以上的运算单元(进程.线程或协程),都在等待对方停止执行,以取得系统资源,但是没有一方提前退出,就称为死锁. 1.死锁演示 死锁的形成分为两个方面,一个是使用 ...

  9. 一文详解Redis键过期策略

    摘要:Redis采用的过期策略:惰性删除+定期删除. 本文分享自华为云社区<Redis键过期策略详解>,作者:JavaEdge. 1 设置带过期时间的 key # 时间复杂度:O(1),最 ...

  10. 一文详解如何在基于webpack5的react项目中使用svg

    本文主要讨论基于webpack5+TypeScript的React项目(cra.craco底层本质都是使用webpack,所以同理)在2023年的今天是如何在项目中使用svg资源的. 首先,假定您已经 ...

随机推荐

  1. 【Vue项目 + 自写java后端】尚品汇(七)后台项目 ElementUI 表单验证 + 三级联动

    ElementUI 表单验证 1 标准验证规则 Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可 ...

  2. 两种路由模式的区别(hash模式,history模式)

    1. hash 带#号的,history不带#号2.hash模式用的hashChange监听路径的变化3.history用的是HTML5相关的API语法 使用pushState => 添加一条历 ...

  3. Nginx配置https并监听80端口重定向到443

    1.进入nginx安装目录,进入config文件夹编辑nginx.conf文件 vim nginx.conf 配置端口  443 listen 443 http2 ssl default_server ...

  4. 使用Jmeter进行CPU、内存等监控

    一.需要的准备 1.jp@gc - PerfMon Metrics Collector插件(安装方法就不过多介绍啦!) 2.ServerAgent服务器(下载:https://github.com/u ...

  5. 跑在笔记本里的大语言模型 - GPT4All

    何为GPT4All GPT4All 官网给自己的定义是:一款免费使用.本地运行.隐私感知的聊天机器人,无需GPU或互联网. 从官网可以得知其主要特点是: 本地运行(可包装成自主知识产权) 无需GPU( ...

  6. 音视频八股文(9)-- flv的h264六层结构和aac六层结构

    flv介绍 FLV(Flash Video)是Adobe公司推出的⼀种流媒体格式,由于其封装后的⾳视频⽂件体积⼩.封装简单等特点,⾮常适合于互联⽹上使⽤.⽬前主流的视频⽹站基本都⽀持FLV.采⽤FLV ...

  7. 2022-07-24:以下go语言代码输出什么?A:[]int{};B:[]int(nil);C:panic;D:编译错误。 package main import ( “fmt“ ) f

    2022-07-24:以下go语言代码输出什么?A:[]int{}:B:[]int(nil):C:panic:D:编译错误. package main import ( "fmt" ...

  8. 2021-02-13:字符串str最少添加多少个字符变成回文串?

    福哥答案2020-02-13: 假设字符串str是"abcde12344321",在str后添加"edcba"即可变成回文串.需要添加5个字符. 解法:包含最后 ...

  9. 2022-01-05:有四种诗的韵律分别为: AABB、ABAB、ABBA、AAAA。 比如 : 1 1 3 3就属于AABB型的韵律、

    2022-01-05:有四种诗的韵律分别为: AABB.ABAB.ABBA.AAAA. 比如 : 1 1 3 3就属于AABB型的韵律.6 6 6 6就属于AAAA型的韵律等等, 一个数组arr,当然 ...

  10. sql server 删除带依赖的列 由于一个或多个对象访问此 列

    --SELECT * FROM LJEL005H--ALTER TABLE LJEL005H add el_req int default 15 not null --消息 5074,级别 16,状态 ...