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