gpt4 book ai didi

一文详解Okio输入输出流

转载 作者:我是一只小鸟 更新时间:2023-07-14 14:31:30 26 4
gpt4 key购买 nike

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

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

1、输入输出

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

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

2、Okio简介

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

Okio主要结构

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

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

3、引入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")

                        
                      

4、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描述如下:

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

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

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

                        
                      

5、参考

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输入输出流的文章就讲到这里了,如果你想了解更多关于一文详解Okio输入输出流的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com