java.io源碼解析(七)--緩沖流(BufferedInputStream,BufferedOutputStream桦锄,BufferedReader扎附,BufferedWriter)

聲明:本系列只供本人自學(xué)使用,勿噴结耀。

緩沖流本質(zhì)上是通過一個(gè)內(nèi)部緩沖區(qū)數(shù)組實(shí)現(xiàn)的留夜。例如,當(dāng)我們通過read()讀取輸入流的數(shù)據(jù)時(shí)图甜,BufferedInputStream會(huì)將該輸入流的數(shù)據(jù)分批的填入到緩沖區(qū)中碍粥。每當(dāng)緩沖區(qū)中的數(shù)據(jù)被讀完之后,輸入流會(huì)再次填充數(shù)據(jù)緩沖區(qū)黑毅;如此反復(fù)即纲,直到我們讀完輸入流數(shù)據(jù)位置。

那么為什么需要內(nèi)部緩沖呢博肋?答案是效率低斋。因?yàn)槠胀ǖ腎nputStream讀取數(shù)據(jù)是需要逐個(gè)字節(jié)讀取,假如原始數(shù)據(jù)是在硬盤上匪凡,那速度會(huì)很慢膊畴。而運(yùn)用BufferedInputStream,則可以一次性讀n個(gè)字節(jié)到內(nèi)存中的緩沖區(qū)病游,這樣在內(nèi)存中讀取數(shù)據(jù)會(huì)快很多唇跨。

一稠通、BufferedInputStream

  • 構(gòu)造器(入?yún)⒈仨氂蠭nputStream )
public class BufferedInputStream extends FilterInputStream{
    private static int DEFAULT_BUFFER_SIZE = 8192;
    private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
    // 緩沖數(shù)組
    protected volatile byte buf[];
    // bufUpdater提供buf的compareAndSet方法,這是必要的买猖,因?yàn)閏lose()可以是異步的改橘,可以將buf是否為null作為是否close的主要指標(biāo)。
    private static final AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> bufUpdater =
        AtomicReferenceFieldUpdater.newUpdater(BufferedInputStream.class,  byte[].class, "buf");
    // buf中的有效字節(jié)數(shù)
    protected int count;
    // buf中的當(dāng)前字節(jié)位置
    protected int pos;
    
    public BufferedInputStream(InputStream in) {
        this(in, DEFAULT_BUFFER_SIZE);
    }

    public BufferedInputStream(InputStream in, int size) {
        super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }
}
  • 核心方法
    // 往buf填充數(shù)據(jù)玉控,方法里主要是考慮到mark的幾種情況
    private void fill() throws IOException

    public synchronized int read() throws IOException {
        // 當(dāng)讀完buf中的數(shù)據(jù)后飞主,就需要把InputStream的數(shù)據(jù)重新填充到buf
        if (pos >= count) {
            fill();
            if (pos >= count)
                return -1;
        }
        // 返回buf的下一個(gè)字節(jié)
        return getBufIfOpen()[pos++] & 0xff;
    }

    private int read1(byte[] b, int off, int len) throws IOException

    // 調(diào)用 read1
    public synchronized int read(byte b[], int off, int len) throws IOException
  • 其他方法
public synchronized long skip(long n) throws IOException
public synchronized int available() throws IOException
public synchronized void mark(int readlimit)
public synchronized void reset() throws IOException
public boolean markSupported()

二、BufferedOutputStream

  • 構(gòu)造器(入?yún)⒈仨氂蠴utputStream )
public class BufferedOutputStream extends FilterOutputStream{
    private static int DEFAULT_BUFFER_SIZE = 8192;
    private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
    // 緩沖數(shù)組
    protected byte buf[];
    // buf中的有效字節(jié)數(shù)
    protected int count;

    public BufferedOutputStream(OutputStream out) {
        this(out, 8192);
    }

    public BufferedOutputStream(OutputStream out, int size) {
        super(out);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }
}
  • 核心方法
    public synchronized void write(int b) throws IOException

    public synchronized void write(byte b[], int off, int len) throws IOException
    
    public synchronized void flush() throws IOException

三高诺、BufferedReader

  • 構(gòu)造器(入?yún)⒈仨氂蠷eader)
public class BufferedInputStream extends FilterInputStream{
    private Reader in;
    private static int defaultCharBufferSize = 8192;
    private static int defaultExpectedLineLength = 80;
    // 緩沖數(shù)組
    private char cb[];
    // 其他 mark相關(guān)變量

    public BufferedReader(Reader in) {
        this(in, defaultCharBufferSize);
    }

    public BufferedReader(Reader in, int sz) {
        super(in);
        if (sz <= 0)
            throw new IllegalArgumentException("Buffer size <= 0");
        this.in = in;
        cb = new char[sz];
        nextChar = nChars = 0;
    }
}
  • 核心方法
public int read() throws IOException
public int read(char cbuf[], int off, int len) throws IOException
public String readLine() throws IOException
  • 其他方法
public long skip(long n) throws IOException
public boolean ready() throws IOException
public boolean markSupported()
public void mark(int readAheadLimit) throws IOException
public void reset() throws IOException
public void close() throws IOException
public Stream<String> lines()

四碌识、BufferedWriter

  • 構(gòu)造器(入?yún)⒈仨氂蠾riter)
public class BufferedWriter extends Writer{
    private Writer out;

    private char cb[];
    private int nChars, nextChar;

    private static int defaultCharBufferSize = 8192;

    private String lineSeparator;

    public BufferedWriter(Writer out) {
        this(out, defaultCharBufferSize);
    }

    public BufferedWriter(Writer out, int sz) {
        super(out);
        if (sz <= 0)
            throw new IllegalArgumentException("Buffer size <= 0");
        this.out = out;
        cb = new char[sz];
        nChars = sz;
        nextChar = 0;

        lineSeparator = java.security.AccessController.doPrivileged(
            new sun.security.action.GetPropertyAction("line.separator"));
    }
}
  • 核心方法
public void write(int c) throws IOException
public void write(char cbuf[], int off, int len) throws IOException
public void write(String s, int off, int len) throws IOException
public void newLine() throws IOException
  • 其他方法
public void flush() throws IOException
public void close() throws IOException
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市虱而,隨后出現(xiàn)的幾起案子筏餐,更是在濱河造成了極大的恐慌,老刑警劉巖牡拇,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件魁瞪,死亡現(xiàn)場離奇詭異,居然都是意外死亡惠呼,警方通過查閱死者的電腦和手機(jī)导俘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來罢杉,“玉大人趟畏,你說我怎么就攤上這事贡歧√沧猓” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵利朵,是天一觀的道長律想。 經(jīng)常有香客問我,道長绍弟,這世上最難降的妖魔是什么技即? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮樟遣,結(jié)果婚禮上而叼,老公的妹妹穿的比我還像新娘。我一直安慰自己豹悬,他們只是感情好葵陵,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瞻佛,像睡著了一般脱篙。 火紅的嫁衣襯著肌膚如雪娇钱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天绊困,我揣著相機(jī)與錄音文搂,去河邊找鬼。 笑死秤朗,一個(gè)胖子當(dāng)著我的面吹牛煤蹭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播川梅,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼疯兼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了贫途?” 一聲冷哼從身側(cè)響起吧彪,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎丢早,沒想到半個(gè)月后姨裸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡怨酝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年傀缩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片农猬。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赡艰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出斤葱,到底是詐尸還是另有隱情慷垮,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布揍堕,位于F島的核電站料身,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏衩茸。R本人自食惡果不足惜芹血,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望楞慈。 院中可真熱鬧幔烛,春花似錦、人聲如沸囊蓝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽慎颗。三九已至乡恕,卻和暖如春言询,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背傲宜。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國打工运杭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人函卒。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓辆憔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親报嵌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子虱咧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350