BufferedOutputStream源码解析

package java.io;


public class BufferedOutputStream extends FilterOutputStream {
    //存储数据的内部缓冲区,存储"缓冲输入流"数据的字节数组
    protected byte buf[];

    //缓冲区中的有效字节数,即缓冲区数据的个数
    protected int count;

    //构造器:创建了一个新的缓存区为默认字节为8192大小的“缓冲输出流”
    public BufferedOutputStream(OutputStream out) {
        this(out, 8192);
    }

    //创建一个新的缓冲输出流,大小为size
    public BufferedOutputStream(OutputStream out, int size) {
        super(out);
        if (size <= 0) {  //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();
        }
         // 将“数据b”写入到缓冲中
        buf[count++] = (byte)b;
    }

    //
    public synchronized void write(byte b[], int off, int len) throws IOException {
         // 若"写入长度len"大于"缓冲区大小",会先进行冲刷,将缓冲中的数据写入到输出流,
         //   然后直接将数组b写入到输出流中
         if (len >= buf.length) {
            flushBuffer();
            out.write(b, off, len);
            return;
        }
        //若"写入的长度len"大于"缓冲区剩余的空间",会先将缓冲区进行冲刷,然后将b[]写入缓冲区
        if (len > buf.length - count) {
            flushBuffer();
        }
        System.arraycopy(b, off, buf, count, len);
        count += len;
    }

    //冲刷,调用flushBuffer()方法,将“缓冲数据”写入到输出流中,
    //flush()方法可以强迫输出流(或缓冲的流)发送数据,即使此时缓冲区还没有填满,以此来打破这种死
    //锁的状态。
    public synchronized void flush() throws IOException {
        flushBuffer();
        out.flush();
    }
}

flush():作用是冲刷缓冲区中的数据,这个作用尤为重要。

例如,缓冲区大小为8192,然后你传入了一个比缓冲区小的文件,这时候因为缓冲区没有满,它不进行自动刷新。

所以我们不进行flush()冲刷的话会造成文件的数据丢失。

所以我们在输出流是BufferOutputStream时,在完成write()后添加flush();

当然如果将流关闭,即使用close()时,可以不进行flush(),因为close()底层源码中有flush()方法;

 write(byte b[], int off, int len)

如果写入的len大于定义的缓冲区大小,会直接写到输出流中,不经过缓冲区。

如果写入的len不大于缓冲区,但是大于缓冲区剩余空间的大小,会先将缓冲区的数据写入输出流中,在将b[]写入缓冲区

你可能感兴趣的:(缓冲输出流,java基础,IO流,flush())