一文详解Android中Okio输入输出流

 更新时间:2023年07月14日 10:33:57   作者:夏天笔语  
在 OkHttp 的源码中,我们经常能看到 Okio 的身影,所以这篇文章文章我们将对Okio进行一个详细的讲解,文中有详细的代码示例供大家参考,需要的朋友可以参考下

一、输入输出

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

  • 输入流:外设——>内存 将数据从各种外设(如键盘、文件、网络、数据库等)读取到内存中;

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

二、Okio简介

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

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

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

三、引入Okio

Okio官方API地址为:Okio (square.github.io)

Okio Github开源地址为: GitHub - square/okio: A modern I/O library for Android, Java, and Kotlin Multiplatform.

使用 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 中,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")));
}

以上就是一文详解Android中Okio输入输出流的详细内容,更多关于Android Okio输入输出流的资料请关注脚本之家其它相关文章!

相关文章

  • Android基于OpenCV实现霍夫直线检测

    Android基于OpenCV实现霍夫直线检测

    霍夫变换利用点与线之间的对偶性,将图像空间中直线上离散的像素点通过参数方程映射为霍夫空间中的曲线,并将霍夫空间中多条曲线的交点作为直线方程的参数映射为图像空间中的直线。给定直线的参数方程,可以利用霍夫变换来检测图像中的直线。本文简单讲解Android的实现
    2021-06-06
  • Android拖拽助手ViewDragHelper的创建与使用实例

    Android拖拽助手ViewDragHelper的创建与使用实例

    ViewDragHelper是针对 ViewGroup 中的拖拽和重新定位 views 操作时提供了一系列非常有用的方法和状态追踪,下面这篇文章主要给大家介绍了关于Android拖拽助手ViewDragHelper的创建与使用的相关资料,需要的朋友可以参考下
    2022-05-05
  • Android编程实现给Button添加图片和文字的方法

    Android编程实现给Button添加图片和文字的方法

    这篇文章主要介绍了Android编程实现给Button添加图片和文字的方法,涉及Android针对按钮元素属性的相关操作技巧,需要的朋友可以参考下
    2015-11-11
  • Android仿微信图片选择器ImageSelector使用详解

    Android仿微信图片选择器ImageSelector使用详解

    这篇文章主要为大家详细介绍了Android仿微信图片选择器ImageSelector的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Android Handler机制详解原理

    Android Handler机制详解原理

    Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分在消息队列中逐一将消息取出,然后对消息进行处理,也就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作
    2021-11-11
  • Android Menu详解及示例代码

    Android Menu详解及示例代码

    本文主要介绍Android Menu,这里对Android菜单(menu)进行了详细的介绍,并给出示例代码和实现效果图,有需要的小伙伴可以参考下
    2016-08-08
  • Android使用WebView实现全屏切换播放网页视频功能

    Android使用WebView实现全屏切换播放网页视频功能

    这篇文章主要介绍了Android使用WebView实现全屏切换播放网页视频功能,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2019-07-07
  • Android源码解析之截屏事件流程

    Android源码解析之截屏事件流程

    这篇文章我们主要讲一下Android系统中的截屏事件处理流程。用过android系统手机的同学应该都知道,一般的android手机按下音量减少键和电源按键就会触发截屏事件.
    2018-05-05
  • Android 仿微信底部渐变Tab效果

    Android 仿微信底部渐变Tab效果

    这篇文章主要介绍了Android 仿微信底部渐变Tab效果,需要的朋友可以参考下
    2017-12-12
  • OpenGL Shader实现物件材料效果详解

    OpenGL Shader实现物件材料效果详解

    在一些主流app上有一些比较特殊的滤镜效果,例如灰尘、塑料封面、光影效果等,这些其实是纹理叠加的效果。本文将用OpenGL Shader实现这些效果,需要的可以参考一下
    2022-02-02

最新评论