首页 > 其他分享 >一文详解 Okio 输入输出流

一文详解 Okio 输入输出流

时间:2023-07-14 10:11:17浏览次数:37  
标签:字节 Buffer 输入输出 Source 详解 Sink Okio okio

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

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

一、输入输出

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

  • 输入流:外设——>内存
    将数据从各种外设(如键盘、文件、网络、数据库等)读取到内存中;
    输入流:外设——>内存
  • 输出流:内存——>外设
    与输入流相反,是将内存数据写入到各种外设(如文件、网络、数据库、显示器等);
    输出流:内存——>外设

二、Okio简介

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

Okio主要结构

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描述如下:
官方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描述如下:
官方API描述

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

ByteString的静态方法

ByteString的公有方法

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主要结构

使用 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技术小馆“,如果文章对您有帮助,欢迎关注我的公众号。
欢迎关注我的公众号

标签:字节,Buffer,输入输出,Source,详解,Sink,Okio,okio
From: https://www.cnblogs.com/xiaxveliang/p/17552924.html

相关文章

  • 详解在Linux中修改Tomcat使用的jdk版本
    问题分析由于部署个人项目使用了openjdk11,但是我之前安装的是jdk1.8,jdk版本升级的后果就是,tomcat运行的时候报一点小bug(因为之前安装tomcat默认使用了系统的jdk版本)所以就想着把tomcat使用的jdk版本调回原来的,找了很多资料之后,决定在tomcat的运行文件中覆盖使用的jdk版本路径......
  • xss-labs靶场1-20关详解
    靶场下载链接https://github.com/do0dl3/xss-labs在线靶场https://xssaq.com/yx/Level1(直接注入)源码<!DOCTYPEhtml><!--STATUSOK--><html><head><metahttp-equiv="content-type"content="text/html;charset=utf-8"><scr......
  • 【Spring Security】的RememberMe功能流程与源码详解
    相关课程前言今天我们来聊一下登陆页面中"记住我"这个看似简单实则复杂的小功能。如图就是某网站登陆时的"记住我"选项,在实际开发登陆接口以前,我一直认为这个"记住我"就是把我的用户名和密码保存到浏览器的cookie中,当下次登陆时浏览器会自动显示我的用户名和密码,就不用我再次......
  • wireshark网络抓包详解
     一、简介Wireshark是一款非常流行的网络封包分析软件,可以截取各种网络数据包,并显示数据包详细信息。为了安全考虑,wireshark只能查看封包,而不能修改封包的内容,或者发送封包。wireshark能获取HTTP,也能获取HTTPS,但是不能解密HTTPS,所以wireshark看不懂HTTPS中的内容二......
  • 直播平台源代码,Silder(滑块,进度条)使用详解
    直播平台源代码,Silder(滑块,进度条)使用详解child:Slider(    onChanged:(value){     setState((){      _silderValue=value;     });    },    //值    value:_silderValue,    //滑块划过的......
  • ​注意力机制中的掩码详解
    注意力机制的掩码允许我们发送不同长度的批次数据一次性的发送到transformer中。在代码中是通过将所有序列填充到相同的长度,然后使用“attention_mask”张量来识别哪些令牌是填充的来做到这一点,本文将详细介绍这个掩码的原理和机制。我们先介绍下如果不使用掩码,是如何运行的。这......
  • 怎么看网站是否开启CDN加速?测试网站全国访问速度方法详解
    注意域名,动静分离的网站,只对静态文件的域名做了cdn怎么看网站有没开启CDN?要看一个网站是否开启CDN,方法很简单,只要在不同的地区ping网址就可以,比如在山东济南ping www.jb51.net 得到的IP地址是111.161.66.167,但在江苏地区ping www.jb51.net得到的IP确是61.147.92.111,像这样在不同......
  • B2B分销流程详解:构建高效B2B分销平台,提高SaaS产品销售额
    当前大部分SaaS产品的分销渠道越来越难找、网络营销门槛越来越高,以至于很多产品苦于无销售渠道难题…… B2B分销平台为了拓宽中小型企业营销渠道,一种新兴的基于B2B模式的商业合作浪潮在SaaS业内火了起来,这种被后来称为“分销”的网络经营理念让很多致力于服务业的SaaS企业找到了自......
  • 集成测试最全详解,看完必须懂了
    什么是集成测试集成测试(IntegrationTesting),也叫组装测试或联合测试。在单元测试的基础上,将所有模块按照设计要求(如根据结构图)组装成为子系统或系统,进行集成测试。集成测试(也叫组装测试,联合测试)是单元测试的逻辑扩展。它最简单的形式是:把两个已经测试过的单元组合成一个组件,测试......
  • 统计平台广告推送工具支持百度、51拉、CNZZ 用法详解
    此软件用于伪造站长统计的搜素关键词,可以模拟百度、360、搜狗等搜索引擎来路 支持自定义刷词次数、多线程支持自定义线程数,速度更快 支持指定网址推广,带来更精确的网站IP来路 一键导入几十万个网站,支持TXT文件导入一行一个网址即可 5.8版界面预览: 可以模拟电脑......