1. 程式人生 > >高效易用的okio(一)

高效易用的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 的概念,下篇開始原始碼的分析