一文详解 Okio 输入输出流
在 OkHttp 的源码中,我们经常能看到 Okio
的身影,这篇文章,我们把Okio
拿出来进行一个详细的介绍学习。
- 输入输出的概念简述
- Okio 简介
- 工程中引入 Okio
- API 简介及使用介绍
一、输入输出
在正式介绍 Okio 之前,让我们先回忆一下输入/输出流
的概念。
输入流:外设——>内存
将数据从各种外设(如键盘、文件、网络、数据库等)读取到内存中;
输出流:内存——>外设
与输入流相反,是将内存数据写入到各种外设(如文件、网络、数据库、显示器等);
二、Okio简介
Okio最初是作为OkHttp的一个组件
出现,是 OkHttp 实现HTTP协议数据构建、解析中使用到的底层 IO 库。其相比于传统的 java.io 和 java.nio ,其在文件
、网络
等数据读写操作更加便捷、高效
。
Okio
的设计思想是将数据的读写
操作封装为一个统一的接口,即 Source
和 Sink
,其中 输入为Source,输出为Sink 。
Okio
还提供了Buffer
和ByteString
用于封装和操作字节数据
,提高数据读写的效率。- 同时,
Okio
还提供了一些工具方法,例如从InputStream
或OutputStream
中创建BufferedSource
、BufferedSink
等。
三、引入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中Buffer
是BufferedSource
和BufferedSink
的接口实现类,用户实现字节数据的缓冲与读写。
官方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
中维护了大小不可变的字节数组
,其可以对存入该字节数组的数据进行base64
、utf8
、md5
、sha256
等字符串的编解码操作。
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 中,Source
和 Sink
用于读取
和写入
数据的抽象类
,其提供了一组标准的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 输入输出流的更多相关文章
- 一文详解Hexo+Github小白建站
作者:玩世不恭的Coder时间:2020-03-08说明:本文为原创文章,未经允许不可转载,转载前请联系作者 一文详解Hexo+Github小白建站 前言 GitHub是一个面向开源及私有软件项目的托 ...
- 一文详解 Linux 系统常用监控工一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)具(top,htop,iotop,iftop)
一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop) 概 述 本文主要记录一下 Linux 系统上一些常用的系统监控工具,非常好用.正所谓磨刀不误砍柴工,花点时间 ...
- StreamingContext详解,输入DStream和Reveiver详解
StreamingContext详解,输入DStream和Reveiver详解 一.StreamingContext详解 1.1两种创建StreamingContext的方式 1.2SteamingC ...
- 小甲鱼PE详解之输入表(导出表)详解(PE详解09)
小甲鱼PE详解之输出表(导出表)详解(PE详解09) 当PE 文件被执行的时候,Windows 加载器将文件装入内存并将导入表(Export Table) 登记的动态链接库(一般是DLL 格式)文件一 ...
- 一文详解 OpenGL ES 3.x 渲染管线
OpenGL ES 构建的三维空间,其中的三维实体由许多的三角形拼接构成.如下图左侧所示的三维实体圆锥,其由许多三角形按照一定规律拼接构成.而组成圆锥的每一个三角形,其任意一个顶点由三维空间中 x.y ...
- 一文详解 WebSocket 网络协议
WebSocket 协议运行在TCP协议之上,与Http协议同属于应用层网络数据传输协议.WebSocket相比于Http协议最大的特点是:允许服务端主动向客户端推送数据(从而解决Http 1.1协议 ...
- 一文详解 Linux Crontab 调度任务
最近接到这样一个任务: 定期(每天.每月)向"特定服务器"传输"软件服务"的运营数据,因此这里涉及到一个定时任务,计划使用Python语言添加Crontab依赖 ...
- 1.3w字,一文详解死锁!
死锁(Dead Lock)指的是两个或两个以上的运算单元(进程.线程或协程),都在等待对方停止执行,以取得系统资源,但是没有一方提前退出,就称为死锁. 1.死锁演示 死锁的形成分为两个方面,一个是使用 ...
- 一文详解Redis键过期策略
摘要:Redis采用的过期策略:惰性删除+定期删除. 本文分享自华为云社区<Redis键过期策略详解>,作者:JavaEdge. 1 设置带过期时间的 key # 时间复杂度:O(1),最 ...
- 一文详解如何在基于webpack5的react项目中使用svg
本文主要讨论基于webpack5+TypeScript的React项目(cra.craco底层本质都是使用webpack,所以同理)在2023年的今天是如何在项目中使用svg资源的. 首先,假定您已经 ...
随机推荐
- 互联网常用API收集
百度车联网API:http://lbsyun.baidu.com/index.php?title=car
- Poe – Fast AI Chat 一款集成AI工具
前言 Poe – Fast AI Chat是由知名问答社区 Quora 开发的 AI 产品,提供实时在线与多个 AI 机器人交流的功能.在去年12月,Quora首次推出Poe作为封闭测试版,并于2月份 ...
- Git提交代码仓库的两种方式
目录 一: 两种本地与远程仓库同步 1 git 远程仓库 提交本地版本库操作 提交到远程版本库操作 1.Git 全局设置: 2.增加一个远程仓库地址 3.查询当前存在的远程仓库 5.本地版本库内容提交 ...
- django restframework的简单使用
django restframework的简单使用 1.快速上手 配置: (pip install djangorestframework==3.12.4) # settings.py INSTALL ...
- 玩转云端 | 算力基础设施升级,看天翼云紫金DPU显身手!
数字时代下,算力成为新的核心生产力,传统以CPU为核心的架构难以满足新场景下快速增长的算力需求,具备软硬加速能力的DPU得以出现并快速发展.天翼云凭借领先的技术和丰富的应用实践自研紫金DPU,打造为云 ...
- 3520. 【NOIP2013模拟11.7B组】原根(math)
题目: 考试想法: 考试的时候觉得这些数学公式太恶心了,所以就直接跳过了. 正解: 直接暴力模拟就可以了. 代码: #include<bits/stdc++.h> using namesp ...
- 京东小程序接入ARVR的技术方案和性能调优
作者:京东零售 戴旭 京东小程序是一个开放技术平台,正在被越来越多的头部品牌选择,用于站内私域流量的营销和运营.诸如各种日化.奢侈品等品牌对ARVR有较多的诉求,希望京东小程序引擎提供一些底层能力,叠 ...
- Rust -- 模式与匹配
1. 模式 用来匹配类型中的结构(数据的形状),结合 模式和match表达式 提供程序控制流的支配权 模式组成内容 字面量 解构的数组.枚举.结构体.元祖 变量 通配符 占位符 流程:匹配值 --&g ...
- 在unity中制作live2d参数的AnimationClip[简单随笔]
假定:已经成功导入模型.相关文档参考:https://github.com/gtf35/live2d_unity_sdk_chinese_document(人力翻译版的Live2d SDK文档) 全部 ...
- 飞行时间技术TOF
文章目录 飞行时间技术TOF 一. 光速的测定 二. 各种TOF技术 直接脉冲TOF 脉冲间接TOF 连续波调制TOF(Continous Wave TOF) 三. TOF技术的应用 飞行时间技术TO ...