Android下的IO庫-Okio源碼解析(肆)

本章非墨將給大家解析一下Okio中的BufferedSource和BufferedSink接口,我們對比jre里面的BufferedInputStream和BufferedOutputStream淮逊。實際上他們從功能上是一模一樣的:

1.為了提高效率,減少IO中斷頻率
2.由于一次性讀取更多的數(shù)據(jù),因此可以對數(shù)據(jù)進行組合使用

我們先來看看Jdk里面是如何處理BufferStream的,以BufferedInputStream為例:

@Override
    public synchronized int read() throws IOException {
        // Use local refs since buf and in may be invalidated by an
        // unsynchronized close()
        byte[] localBuf = buf;
        InputStream localIn = in;
        if (localBuf == null || localIn == null) {
            throw streamClosed();
        }

        /* Are there buffered bytes available? */
        if (pos >= count && fillbuf(localIn, localBuf) == -1) {//一次性讀取多個數(shù)據(jù)
            return -1; /* no, fill buffer */
        }
        // localBuf may have been invalidated by fillbuf
        if (localBuf != buf) {
            localBuf = buf;
            if (localBuf == null) {
                throw streamClosed();
            }
        }

        /* Did filling the buffer fail with -1 (EOF)? */
        if (count - pos > 0) {
            return localBuf[pos++] & 0xFF;
        }
        return -1;
    }

我們可以看到,在BufferedInputStream中,實際上是生成了一個buf數(shù)組,即使你一次性只是讀取一個字節(jié)的數(shù)據(jù),BufferedInputStream一樣會通過一個buf(緩存)變量來讀取多個的數(shù)據(jù)饥伊。這樣當(dāng)你在讀取下一個數(shù)據(jù)的時候就可以直接在進程內(nèi)的內(nèi)存數(shù)據(jù),而不涉及操作系統(tǒng)的系統(tǒng)調(diào)用戴甩。
我們再回到Okio中,之前我們說過,Okio的很多概念都可以對標(biāo)jdk中的流,之間的映射關(guān)系基本如下表:

1.Source->InputStream
2.Sink->OutputStream
3.Buffer->byte[]
4.BufferedSource->BufferedInputStream
5.BufferedSink->BufferedOuputStream
有了以上的只是儲備,我們可以更好的理解Okio的Buffered相關(guān)代碼停忿。

以BufferedSource為例,我們來看下Okio是如何實現(xiàn)的。BufferedSource本身是一個接口,我們可以通過接口定義看出它跟Source本身的區(qū)別:

Source本身只承擔(dān)最為基本的數(shù)據(jù)讀取,BufferedSource可以通過數(shù)據(jù)拼裝成為各種的數(shù)據(jù)類型

public interface BufferedSource extends Source {
  /** Returns this source's internal buffer. */
  Buffer buffer();//Buffered內(nèi)部自定義的Buffer對象

  /**
   * Returns true if there are no more bytes in this source. This will block until there are bytes
   * to read or the source is definitely exhausted.
   */
  boolean exhausted() throws IOException;//看下此Buffer是否耗盡

  /**
   * Returns when the buffer contains at least {@code byteCount} bytes. Throws an
   * {@link java.io.EOFException} if the source is exhausted before the required bytes can be read.
   */
  void require(long byteCount) throws IOException;//查看是否還有byteCount長度的字段

  /**
   * Returns true when the buffer contains at least {@code byteCount} bytes, expanding it as
   * necessary. Returns false if the source is exhausted before the requested bytes can be read.
   */
  boolean request(long byteCount) throws IOException;//請求byteCount長度的數(shù)據(jù)

  /** Removes a byte from this source and returns it. */
  byte readByte() throws IOException;
 ....
}

在Okio類的靜態(tài)方法buffer中,構(gòu)造了這個BufferedSource對象,而這個接口的實現(xiàn)類是RealBufferedSource的類:

public static BufferedSource buffer(Source source) {
    return new RealBufferedSource(source);
  }
final class RealBufferedSource implements BufferedSource {
  public final Buffer buffer = new Buffer();//內(nèi)部定義的buffer
  public final Source source;//被裝飾的source
  boolean closed;
....
}

我們著重看一下它的read()方法:

@Override public long read(Buffer sink, long byteCount) throws IOException {
    if (sink == null) throw new IllegalArgumentException("sink == null");
    if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
    if (closed) throw new IllegalStateException("closed");

    if (buffer.size == 0) {
      long read = source.read(buffer, Segment.SIZE);//從source中讀入數(shù)據(jù)到內(nèi)部的Buffer中
      if (read == -1) return -1;
    }

    long toRead = Math.min(byteCount, buffer.size);
    return buffer.read(sink, toRead);//從內(nèi)部的buffer拷貝到sink目標(biāo)buffer
  }

RealBufferedSource的做法,一樣是先通過一個Buffer來預(yù)取數(shù)據(jù),然后通過拷貝的方式拷貝到sink目標(biāo)緩存中。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市又碌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绊袋,老刑警劉巖毕匀,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異癌别,居然都是意外死亡皂岔,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門展姐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來躁垛,“玉大人,你說我怎么就攤上這事圾笨〗坦荩” “怎么了晶府?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵兜粘,是天一觀的道長扒吁。 經(jīng)常有香客問我赵誓,道長,這世上最難降的妖魔是什么告私? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任馁龟,我火速辦了婚禮蹋盆,結(jié)果婚禮上俭令,老公的妹妹穿的比我還像新娘后德。我一直安慰自己,他們只是感情好抄腔,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布探遵。 她就那樣靜靜地躺著,像睡著了一般妓柜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上涯穷,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天棍掐,我揣著相機與錄音,去河邊找鬼拷况。 笑死作煌,一個胖子當(dāng)著我的面吹牛掘殴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播粟誓,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼奏寨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鹰服?” 一聲冷哼從身側(cè)響起病瞳,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎悲酷,沒想到半個月后套菜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡设易,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年逗柴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片顿肺。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡戏溺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出屠尊,到底是詐尸還是另有隱情旷祸,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布知染,位于F島的核電站肋僧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏控淡。R本人自食惡果不足惜嫌吠,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掺炭。 院中可真熱鬧辫诅,春花似錦、人聲如沸涧狮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽者冤。三九已至肤视,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涉枫,已是汗流浹背邢滑。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留愿汰,地道東北人困后。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓乐纸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親摇予。 傳聞我的和親對象是個殘疾皇子汽绢,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1.OkHttp源碼解析(一):OKHttp初階2 OkHttp源碼解析(二):OkHttp連接的"前戲"——HT...
    隔壁老李頭閱讀 10,689評論 24 42
  • Okio的傳送門 https://github.com/square/okio 了解Okio之前先了解一個裝飾者模...
    大批閱讀 536評論 0 2
  • 參考資源 官網(wǎng) 國內(nèi)博客 GitHub官網(wǎng) 鑒于一些關(guān)于OKHttp3源碼的解析文檔過于碎片化,本文系統(tǒng)的侧戴,由淺入...
    風(fēng)骨依存閱讀 12,472評論 11 82
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理宁昭,服務(wù)發(fā)現(xiàn)救鲤,斷路器久窟,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • 成品這樣 先畫個橢圓,再定五官位置 這個他自己橫著了… 畫好五官本缠,調(diào)整臉型 上色 完成…
    閻浮小學(xué)僧閱讀 666評論 5 4