Okio深入分析——基礎使用部分

一、前言

Okio的分析是為分析OkHttp打基礎的,當然,其實不瞭解也沒有關係,但是對於知識的體系化總會覺得像是缺了點什麼。而且相較於Java原的IO而言,其包含了非常多的特性,使得其在性能 以使用上非常的出色和容易。面對如此短小精悍的優秀代碼,還有什麼理由拒絕學習它呢?這篇文章先來了解一下其具備的特性以及基礎的一些用法。

二、基本特性

1.基本特性

(1)緊湊的封裝

是對Java IO/NIO 的一個非常優秀的封裝,絕對的“短小精焊”,不僅支持文件讀寫,也支持Socket通信的讀寫。

(2) 使用簡單

不用區分字符流或者字節流,也不用記住各種不同的輸入/輸出流,統統只有一個輸入流Source和一個輸出流Sink。

(3)API豐富

其封裝了大量的API接口用於讀/寫字節或者一行文本

(4)讀寫速度快

這得益於其優秀的緩衝機制和處理內存的技巧,使I/O在緩衝區得到更高的複用處理,從而儘量減少I/O的實際發生。

2.支撐機制

與這些特性相比,就是其有強大的保障機制保駕護航

(1)超時機制

在讀/寫時增加了超時機制,且有同步與異步之分。

(2)緩衝機制

讀/寫都是基於緩衝來來實現,儘量減少實際的I/O。

(3)壓縮機制

寫數據時,會對緩衝的每個Segment進行壓縮,避免空間的浪費。當然,這是其內部的優化技巧,提高內存利用率。

(4)共享機制

主要是針對 Segment 而言的,對於不同的 buffer 可以共享同一個 Segment。這也是其內部的優化技巧。

3.兩個核心基礎類

然而,在正式分析之前有兩個核心基礎類ByteStringBuffer和兩個核心API類需要提前理解一下,因為大量的API都是以這4個類為基礎來實現的。瞭解它們,以便有助於後面的分析。

ByteString 是一個不可變的字節序列。對於字符數據,String是基礎,ByteString則是String失散多年的好兄弟。其可以很容易地將二進制數據視為一個值來處理。如用十六進制,base64,和UTF-8來進行編碼和解碼。Buffer是一個可變的字節序列。就像ArrayList一樣,可以進行靈活的訪問,插入與移除,完全不需要自己去動手管理。這兩個類也是上面機制的實現,正是上面機制的實現,才使得該庫以最少的實際IO來實現快速的IO需求。

三、基本使用

主要以官方demo加上自己的理解和知識來進行講解

1.讀取文本

<code>public void readLines(File file) throws IOException {
// 1.構建 Source
try (Source fileSource = Okio.source(file);
// 2.構建 BufferedSource
BufferedSource bufferedSource = Okio.buffer(fileSource)) {

while (true) {
// 3.按 utf8 的格式逐行讀取字符
String line = bufferedSource.readUtf8Line();
if (line == null) break;

if (line.contains("square")) {
System.out.println(line);
}
}

}
}
/<code>

這是一段按行讀取文本的代碼,其首先構建一個Source,類似於Java的InputStream,然後構建一個BufferedSource,類似於Java的BufferedInputStream,最後就可以直接按行讀取文本了。看起來是不是很簡單呢。在對讀取有了一定的認識後,再深入看看Okio都提供了哪些讀取的API。先一個讀取相關的類圖。

Okio深入分析——基礎使用部分

Source.jpg


從使用者的角度來看,我們所需要了解的就是Source以及BufferedSource這兩個接口即可,具體的實現在RealBufferedSource,真的就這麼多了,是不是很簡單。而在BufferedSource中可以看到,其封裝了大量的API,足夠滿足我們絕大部分的需求了,功能是不是很強大。每次的讀取是基於緩衝機制的,這就提高了讀取的速度。

Demo中舉例是讀取文本,但如果要按字節方式讀取的話,就使用BufferedSource#readByte()即可。或者如果文件是自己定義的特殊結構,可以直接調用 readInt(),readLong() 等方法。

2.寫入文本

<code>public void writeEnv(File file) throws IOException {
// 1.構建 Sink
try (Sink fileSink = Okio.sink(file);
// 2.構建 BufferedSink
BufferedSink bufferedSink = Okio.buffer(fileSink)) {
// 3.寫入文本
for (Map.Entry<string> entry : System.getenv().entrySet()) {
bufferedSink.writeUtf8(entry.getKey());
bufferedSink.writeUtf8("=");
bufferedSink.writeUtf8(entry.getValue());
bufferedSink.writeUtf8("\\n");
}

}
}
/<string>/<code>

這段代碼演示瞭如何寫入一個文本到文件。其先構建一個Sink,類似於Java的OutputStream,再構建一個BufferedSink,類似於Java的 BufferedOutputStream。然後就可以寫入文本了。同樣,是不是很簡單呢。也先來看看寫入相關的類圖。


Okio深入分析——基礎使用部分

Sink.jpg


幾乎就是和讀取的類圖有著一一對應的API。對於開發者來說,瞭解上面的這些接口也就夠了,其豐富的寫入API也幾乎能滿足我們絕大部分的需求了。

四、總結

真的很簡單,以致於不知該總結什麼了,特性以及該說的都在上面說了。當然,知其然而不知其所以然,始終會讓人覺得不爽。下一篇再深入瞭解其具體的封裝和強大保障機制的實現。我們要知道它為什麼好,為什麼快。


分享到:


相關文章: