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

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