BufferedInputStream流的核心在于预先向缓冲区读入流,read()方法是在缓冲区上操作的(),当使用read()方法读取到缓冲区的末尾时,会使用fill()方法再次预先读入一部分字节。
BufferedInputStream类中重要的是fill()函数,下面写一下fill()函数的分析
private void fill() throws IOException {
byte[] buffer = getBufIfOpen();
//如果没有标记,将pos直接重置
if (markpos < 0)
pos = 0; /* no mark: throw away the buffer */
//markpos >= 0 &&pos >= buffer.length
else if ( pos >= buffer.length) /* no room left in buffer */
//将数组前移, markpos == 0
if (markpos > 0) { /* can throw away early part of the buffer */
int sz = pos - markpos;
System.arraycopy(buffer, markpos, buffer, 0, sz);
pos = sz;
markpos = 0;
} else if (buffer.length >= marklimit) {
markpos = -1; /* buffer got too big, invalidate mark */
pos = 0; /* drop buffer contents */
} else if (buffer.length >= MAX_BUFFER_SIZE) {
throw new OutOfMemoryError("Required array size too large");
} else { /* grow buffer */
int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?
pos * 2 : MAX_BUFFER_SIZE;
if (nsz > marklimit)
nsz = marklimit;
byte nbuf[] = new byte[nsz];
System.arraycopy(buffer, 0, nbuf, 0, pos);
if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {
// Can't replace buf if there was an async close.
// Note: This would need to be changed if fill()
// is ever made accessible to multiple threads.
// But for now, the only way CAS can fail is via close.
// assert buf == null;
throw new IOException("Stream closed");
}
buffer = nbuf;
}
count = pos;
int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
if (n > 0)
count = n + pos;
}
网友评论