高效易用的okio(一)
okio 作為 okhttp 的底層 IO 庫,對比 Java 的原生 IO ,提供了更靈活易用的API 來處理資料流的輸入和輸出,某程度上,我們可以放棄 Java 的原生 IO,轉為使用 okio 作為 日常開發的 IO 框架
Java 的原生 IO
在正式介紹 okio之前,我們有必要先來回顧一下 Java IO 的一些基礎知識
程式內部和外部進行資料互動的過程,這個輸入輸出(input/output) 的過程,就是 IO
在 Java 的世界裡面,IO 是一種流的概念,所有的 IO 操作可以被看作是位元組在流中的移動
下面我們來看下,使用 Java IO 讀寫檔案的操作吧,這裡讀取一下本地的 txt 文字:
public void javaIO(View view) {
String mPath = getCacheDir() + File.separator + "article.txt";
long start = System.nanoTime();
try {
BufferedReader reader = new BufferedReader(new FileReader(mPath));
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
Log.e("IO", builder.toString());
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e. printStackTrace();
} finally {
Log.e("IO", "javaIO 耗時為: " + (System.nanoTime() - start));
}
}
然後就可以看到下面的輸出結果了:
可以看到順利讀取到本地的文字,程式碼執行耗時為:1134385
但是就這麼一個簡單需求就要寫這麼一大堆程式碼, 一次兩次或者還可以忍受,但是次數多了,不覺得 Java 原生 IO 的 API,太笨重了嗎?
okio
okio 重新定義了一系列的 IO API,用了兩個全新的 API 來表示輸入流和輸出流
- Sources:輸入流,同 Java IO 中的 InputStream
- Sinks:輸出流,同 Java IO 中的 OutputStream
我們先來看下使用 okio 實現同意的需求應該怎麼去寫:
public void okio(View view) {
String mPath = getCacheDir() + File.separator + "article.txt";
long start = System.nanoTime();
try {
Source source = Okio.source(new File(mPath));
String read = Okio.buffer(source).readString(Charset.forName("utf-8"));
Log.e("IO", read);
source.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
Log.e("IO", "okio耗時為: " + (System.nanoTime() - start));
}
}
使用 okio 實現同樣的功能,明顯輕鬆得多,而且 okio中的類被特意地設計為支援鏈式呼叫,而使用鏈式呼叫,就能產生簡潔、優美、易讀的程式碼,最關鍵是 API 特別友好,對比 Java IO,感覺都可以放棄原生 IO 了
而且這裡我們可以看到,一樣是對本地文字的讀寫,okio 的執行效率比 Java IO 快了很多,耗時僅為 728462,這個是為什麼呢?
阻塞 IO 與 非阻塞 IO
想知道 okio 的效率為什麼要比 Java 的原生 IO 高,就要先搞明白什麼叫做 阻塞 IO 和 非阻塞 IO
- 阻塞 IO:當請求的資源(本地檔案,網路資料等)時,如果遇到資源暫不可訪問的情況,阻塞 IO 會一直原地等待,不斷重複嘗試讀取資料,直到讀取到資料或超時為止,期間執行緒一直都處於阻塞狀態, CPU 利用率極低
- 非阻塞 IO:當請求的資源暫時不可用時,就立即返回,不會阻塞執行緒,隔一段時間後再去請求資源,直到資源請求成功並順利進入讀寫階段,在進入讀寫階段前, CPU 可以去幹別的事情, 利用率得到極大的提高
由此,我們可以知道 Java 的原生 IO 就是一種 阻塞 IO,它是個傻大個,在得到想要的結果之前就只會傻傻得原地等待
而 okio 則是給傻大個充值了一筆智商稅,如果暫時無法得到想要的結果,就會先去幹別的事情,比方說打掃下衛生,喝杯水,然後再去看下能否得到想要的結果
非阻塞IO 本身並不會比 阻塞IO 快,但是它能一定程度提高 CPU 的執行效率 ,提現出來就是更快的處理速度了
總結
這裡先簡單介紹一下 okio 的簡單用法以及一些 IO 的概念,下篇開始原始碼的分析