一文詳解Android中Okio輸入輸出流
一、輸入輸出
在正式介紹 Okio 之前,讓我們先回憶一下輸入/輸出流的概念。
輸入流:外設(shè)——>內(nèi)存將數(shù)據(jù)從各種外設(shè)(如鍵盤、文件、網(wǎng)絡(luò)、數(shù)據(jù)庫等)讀取到內(nèi)存中;

-
輸出流:內(nèi)存——>外設(shè)與輸入流相反,是將內(nèi)存數(shù)據(jù)寫入到各種外設(shè)(如文件、網(wǎng)絡(luò)、數(shù)據(jù)庫、顯示器等);

二、Okio簡介
Okio最初是作為OkHttp的一個(gè)組件出現(xiàn),是 OkHttp 實(shí)現(xiàn)HTTP協(xié)議數(shù)據(jù)構(gòu)建、解析中使用到的底層 IO 庫。其相比于傳統(tǒng)的 java.io 和 java.nio ,其在文件、網(wǎng)絡(luò)等數(shù)據(jù)讀寫操作更加便捷、高效。

Okio 的設(shè)計(jì)思想是將數(shù)據(jù)的讀寫操作封裝為一個(gè)統(tǒng)一的接口,即 Source 和 Sink,其中 輸入為Source,輸出為Sink 。
Okio還提供了Buffer和ByteString用于封裝和操作字節(jié)數(shù)據(jù),提高數(shù)據(jù)讀寫的效率。- 同時(shí),
Okio還提供了一些工具方法,例如從InputStream或OutputStream中創(chuàng)建BufferedSource、BufferedSink等。
三、引入Okio
Okio官方API地址為:Okio (square.github.io)
Okio Github開源地址為: GitHub - square/okio: A modern I/O library for Android, Java, and Kotlin Multiplatform.
使用 Okio 時(shí),我們可以查閱官方最新版本,并通過如下方式引入Okio:
implementation("com.squareup.okio:okio:3.2.0")四、API 簡介及使用
- Buffer 簡介及API使用介紹
- ByteString 簡介及API使用介紹
- Source 和 Sink 使用介紹
4.1 Buffer
Buffer 是一個(gè)大小可變的字節(jié)緩沖區(qū),在Okio中Buffer是BufferedSource和BufferedSink的接口實(shí)現(xiàn)類,用戶實(shí)現(xiàn)字節(jié)數(shù)據(jù)的緩沖與讀寫。

官方API描述如下:
Buffer可以像Arraylist一樣,不需要預(yù)先設(shè)置緩沖區(qū)的大小,而是隨著數(shù)據(jù)的增加自動(dòng)擴(kuò)充緩沖區(qū)大小。Buffer由很多的Segment片段構(gòu)成,每個(gè)Segment中維護(hù)一個(gè)字節(jié)數(shù)組。Buffer中以鏈表的形式來管理Segment,當(dāng)使用Buffer進(jìn)行緩沖區(qū)字節(jié)數(shù)據(jù)移動(dòng)時(shí),其只改變Segment字節(jié)數(shù)組的所有權(quán),從而提高字節(jié)數(shù)組的移動(dòng)效率。
okio.Buffer字節(jié)緩沖區(qū)的使用方式舉例如下:
import okio.Buffer;
Buffer buffer = new Buffer();
// 向緩沖區(qū)寫入數(shù)據(jù)
buffer.writeUtf8("key");
buffer.writeByte('=');
buffer.writeUtf8("value");
// 緩沖區(qū)字節(jié)大小
int byteCount = buffer.size();
// 讀取換區(qū)中的全部字節(jié)數(shù)據(jù)
byte[] byteArray = buffer.readByteArray();
// 以Utf8編碼的形式輸出所有字符串
String result = buffer.readUtf8();
// 清空緩沖區(qū)
buffer.clear();4.2 ByteString
ByteString 中維護(hù)了大小不可變的字節(jié)數(shù)組,其可以對存入該字節(jié)數(shù)組的數(shù)據(jù)進(jìn)行base64、utf8、md5、sha256等字符串的編解碼操作。 ByteString 更像是一個(gè)工具類,在Okio中其重要應(yīng)用場景也是在網(wǎng)絡(luò)傳輸中對數(shù)據(jù)進(jìn)行編碼和解碼工作。
官方API描述如下:

其部分靜態(tài)方法和公有方法如下圖所示:


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 用于讀取和寫入數(shù)據(jù)的抽象類,其提供了一組標(biāo)準(zhǔn)的IO讀寫方法,可以方便地進(jìn)行數(shù)據(jù)的讀寫操作。
// Okio源碼:輸入流 Source
// Source 接口類,最主要的方法是 read
public interface Source extends Closeable {
// 讀字節(jié)數(shù)據(jù)
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 {
// 寫字節(jié)數(shù)據(jù)
void write(Buffer var1, long var2) throws IOException;
void flush() throws IOException;
Timeout timeout();
void close() throws IOException;
}在把前文已經(jīng)展示過的Okio結(jié)構(gòu)圖拿出來:
Source的最終實(shí)現(xiàn)類是RealBufferedSource;Sink的最終實(shí)現(xiàn)類是RealBufferedSink;

使用 okio.Source 從文件中讀取數(shù)據(jù),代碼舉例如下:
// 使用 Source 從文件中讀取數(shù)據(jù)
public static void readLines(File file) throws IOException {
// 輸入流
Source fileSource = Okio.source(file);
// 構(gòu)建 BufferedSource
RealBufferedSource bufferedSource = Okio.buffer(fileSource);
// 循環(huán)讀取
while (true) {
// 讀取行數(shù)據(jù)
String line = bufferedSource.readUtf8Line();
if (line == null) {
break;
}
}
}使用 okio.Sink 向文件中寫入數(shù)據(jù),代碼舉例如下:
// 使用 Sink 向文件中寫入數(shù)據(jù)
public static void writeToFile(File file) throws IOException {
// 創(chuàng)建輸出流
Sink fileSink = Okio.sink(file);
// 構(gòu)造 BufferedSink
RealBufferedSink bufferedSink = Okio.buffer(fileSink);
// 向文件中寫入數(shù)據(jù)
bufferedSink.writeUtf8("Hello");
bufferedSink.writeUtf8("\n");
bufferedSink.writeAll(Okio.source(new File("my.txt")));
}以上就是一文詳解Android中Okio輸入輸出流的詳細(xì)內(nèi)容,更多關(guān)于Android Okio輸入輸出流的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于Android實(shí)現(xiàn)三維效果的動(dòng)態(tài)旋轉(zhuǎn)圖
在電商、相冊、視頻封面、海報(bào)展示、啟動(dòng)頁 Logo 等場景里,帶真實(shí)透視感的 3D 旋轉(zhuǎn)能明顯提升界面質(zhì)感,Android 自 3.x 起就支持基于屬性的 3D 旋轉(zhuǎn),所以本文給大家介紹了如何基于Android實(shí)現(xiàn)三維效果的動(dòng)態(tài)旋轉(zhuǎn)圖,需要的朋友可以參考下2025-09-09
Android自定義View實(shí)現(xiàn)QQ消息氣泡
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)QQ消息氣泡,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
Android實(shí)現(xiàn)類似iOS風(fēng)格的對話框?qū)嵗a
通過本文給大家分享一個(gè)簡單的常用的對話框類,關(guān)于Android實(shí)現(xiàn)類似iOS風(fēng)格的對話框?qū)嵗a大家通過本文學(xué)習(xí)下吧2017-09-09
Flutter質(zhì)感設(shè)計(jì)之直接輸入
這篇文章主要為大家詳細(xì)介紹了Flutter質(zhì)感設(shè)計(jì)之直接輸入,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08
Android中使用socket通信實(shí)現(xiàn)消息推送的方法詳解
這篇文章主要介紹了Android中使用socket通信實(shí)現(xiàn)消息推送的方法,文中舉了一個(gè)消息發(fā)送端和一個(gè)消息接收端以及服務(wù)器端的例子來說明原理并且展示了客戶端的實(shí)現(xiàn),需要的朋友可以參考下2016-04-04
Android開發(fā)之ToggleButton實(shí)現(xiàn)開關(guān)效果示例
這篇文章主要介紹了Android開發(fā)之ToggleButton實(shí)現(xiàn)開關(guān)效果的方法,結(jié)合實(shí)例形式分析了ToggleButton控件實(shí)現(xiàn)開關(guān)效果的布局與功能相關(guān)操作技巧,需要的朋友可以參考下2017-07-07
android 獲取視頻,圖片縮略圖的具體實(shí)現(xiàn)
android 獲取視頻,圖片縮略圖的具體實(shí)現(xiàn),需要的朋友可以參考一下2013-06-06
Android不使用自定義布局情況下實(shí)現(xiàn)自定義通知欄圖標(biāo)的方法
這篇文章主要介紹了Android不使用自定義布局情況下實(shí)現(xiàn)自定義通知欄圖標(biāo)的方法,實(shí)例分析了Android通知欄圖標(biāo)的創(chuàng)建技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-12-12

