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