read(byte[] arr, int off, int len)函数
该函数用来将off位置大小为len的数据拷贝到arr字节数组中,代码如下:
@Override
public synchronized int read(byte[] arr, int off, int len)
throws IOException {
boolean canSkipChecksum = createNoChecksumContext();
int nRead;
try {
String traceString = null;
if (LOG.isTraceEnabled()) {
traceString = new StringBuilder().
append("read(arr.length=").append(arr.length).
append(", off=").append(off).
append(", len=").append(len).
append(", filename=").append(filename).
append(", block=").append(block).
append(", canSkipChecksum=").append(canSkipChecksum).
append(")").toString();
LOG.trace(traceString + ": starting");
}
try {
if (canSkipChecksum && zeroReadaheadRequested) {
//跳过文件校验
nRead = readWithoutBounceBuffer(arr, off, len);
} else {
//需要进行文件校验
nRead = readWithBounceBuffer(arr, off, len, canSkipChecksum);
}
} catch (IOException e) {
if (LOG.isTraceEnabled()) {
LOG.trace(traceString + ": I/O error", e);
}
throw e;
}
if (LOG.isTraceEnabled()) {
LOG.trace(traceString + ": returning " + nRead);
}
} finally {
if (canSkipChecksum) releaseNoChecksumContext();
}
return nRead;
}
函数readWithoutBounceBuffer(byte arr[], int off,int len)代码如下:
private synchronized int readWithoutBounceBuffer(byte arr[], int off,
int len) throws IOException {
//回收释放dataBuf对应的空间
freeDataBufIfExists();
//回收释放checksumBuf对应的空间
freeChecksumBufIfExists();
//将dataIn中从dataPos位置的数据读入到arr中,要么塞满arr,要么dataIn没有数据可读了
int nRead = dataIn.read(ByteBuffer.wrap(arr, off, len), dataPos);
if (nRead > 0) {
dataPos += nRead;
} else if ((nRead == 0) && (dataPos == dataIn.size())) {
return -1;
}
return nRead;
}
函数readWithBounceBuffer(byte arr[], int off, int len,boolean canSkipChecksum) 代码如下:
private synchronized int readWithBounceBuffer(byte arr[], int off, int len,
boolean canSkipChecksum) throws IOException {
//如果dataBuf为null那么先从缓存中获取,如果缓存中没有那么就创建一个,分配堆外内存
createDataBufIfNeeded();
if (!dataBuf.hasRemaining()) {
dataBuf.position(0);
dataBuf.limit(maxReadaheadLength);
//将数据读入到dataBuf中
fillDataBuf(canSkipChecksum);
}
if (dataBuf.remaining() == 0) return -1;
int toRead = Math.min(dataBuf.remaining(), len);
dataBuf.get(arr, off, toRead);
return toRead;
}
这个函数中回去获取相应的数据,如果需要校验的话也会去校验,如果校验失败会抛出异常,fillDataBuf函数中调用的函数在“BlockReaderLocal类中read(ByteBuffer buf)函数”有详解,这里不再赘述。