BufferedOutputStream 源碼的個人理解

package java.io;

/**
 * The class implements a buffered output stream. By setting up such
 * an output stream, an application can write bytes to the underlying
 * output stream without necessarily causing a call to the underlying
 * system for each byte written.
 *
 * @author  Arthur van Hoff
 * @since   JDK1.0
 */
public
class BufferedOutputStream extends FilterOutputStream {
    /**
     * buf[]數組是一個用來存儲數據的緩衝器
     */
    protected byte buf[];

    /**
     * 緩衝其中的實際字節數,範圍0~buf.length
     */
    protected int count;

    /**
     * 構造器1 調用了構造器2,創建一個新的緩衝輸出流對象,默認大小是8K
     */
    public BufferedOutputStream(OutputStream out) {
        this(out, 8192);
    }

    /**
     * 構造器2,可以指定緩衝器的大小,並且調用了父類的構造方法,將傳入的輸出流對象,傳遞給了out成員變量(在父類FilterOutputStream中定義)
     */
    public BufferedOutputStream(OutputStream out, int size) {
        super(out);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

    /** 如果當前緩衝器不爲空,則將緩衝器中的數據全部寫到輸出流中,計數器清零 */
    private void flushBuffer() throws IOException {
        if (count > 0) {
            out.write(buf, 0, count);
            count = 0;
        }
    }

    /**
     * 如果緩衝器滿,則將數據全部寫入輸出流,如果緩衝器不滿,則將數據傳入緩衝器中
     */
    public synchronized void write(int b) throws IOException {
        if (count >= buf.length) {
            flushBuffer();
        }
        buf[count++] = (byte)b;
    }

    /**
     * 寫一個字節數組,寫之前判斷len(將要寫入的字節數組長度)是否大於緩衝區長度,大於的話
     * 就將緩衝區中的數據寫入到輸出流,然後調用傳進來的out對象對應的類的write方法
     *(假設我傳進去的out方法是FileOutputStream的對象,那調用的就是FileOutputStream的方法了)
     *(注意不能拋開代碼去看源碼,我之前只注意到BufferedOutputStream的構造方法裏限定的參數類型是OutputStream,
     * 然後去查outputStream的write方法,到最後發現write(int b)是一個抽象函數,結果就懵逼了)
     * 如果len的長度,小於緩衝區長度但是大於緩衝區剩餘空間
	 * 則需要將緩衝區的數據寫入到輸出流,然後將數組複製到緩衝區中
     */
    public synchronized void write(byte b[], int off, int len) throws IOException {
        if (len >= buf.length) {
            /* If the request length exceeds the size of the output buffer,
               flush the output buffer and then write the data directly.
               In this way buffered streams will cascade harmlessly. */
            flushBuffer();
            out.write(b, off, len);
            return;
        }
        if (len > buf.length - count) {
            flushBuffer();
        }
        System.arraycopy(b, off, buf, count, len);
        count += len;
    }

    /**
     * 強制將buf數據中未滿的數據寫入底層io中(當調用close方法的時候,close方法會調用flush方法)
     * 這裏實際上就flushBuffer()這一句起作用,
     * out.flush()的flush是父類的方法,它裏面根本就沒實現什麼東西,可能是Java開發人員出於某種考慮留下的吧
     */
    public synchronized void flush() throws IOException {
        flushBuffer();
        out.flush();
    }
}


參考文章 http://blog.csdn.net/u013279866/article/details/68489125

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章