public int read ( long position , byte [ ] buffer , int offset , int length , ReadOptions options ) throws IOException { // sanity checks dfsClient . checkOpen ( ) ; if ( closed ) { throw new IOException ( "Stream closed" ) ; } DFSClient . dfsInputStreamfailures . set ( 0 ) ; long start = System . currentTimeMillis ( ) ; long filelen = getFileLength ( ) ; if ( ( position < 0 ) || ( position >= filelen ) ) { return - 1 ; } int realLen = length ; if ( ( position + length ) > filelen ) { realLen = ( int ) ( filelen - position ) ; } DFSReadProfilingData pData = DFSClient . getDFSReadProfilingData ( ) ; // determine the block and byte range within the block // corresponding to position and realLen List < LocatedBlock > blockRange = getBlockRange ( position , realLen ) ; if ( ! tryPreadFromLocal ( blockRange , position , buffer , offset , length , realLen , start ) ) { // non-local or multiple block read. int remaining = realLen ; for ( LocatedBlock blk : blockRange ) { long targetStart = position - blk . getStartOffset ( ) ; long bytesToRead = Math . min ( remaining , blk . getBlockSize ( ) - targetStart ) ; if ( dfsClient . allowParallelReads && dfsClient . parallelReadsThreadPool != null ) { fetchBlockByteRangeSpeculative ( blk , targetStart , targetStart + bytesToRead - 1 , buffer , offset , options ) ; } else { if ( pData != null ) { cliData = new FSClientReadProfilingData ( ) ; pData . addDFSClientReadProfilingData ( cliData ) ; cliData . startRead ( ) ; } fetchBlockByteRange ( blk , targetStart , targetStart + bytesToRead - 1 , buffer , offset , options ) ; if ( pData != null ) { cliData . endRead ( ) ; } } remaining -= bytesToRead ; position += bytesToRead ; offset += bytesToRead ; } assert remaining == 0 : "Wrong number of bytes read." ; } if ( dfsClient . stats != null ) { dfsClient . stats . incrementBytesRead ( realLen ) ; } long timeval = System . currentTimeMillis ( ) - start ; dfsClient . metrics . incPreadTime ( timeval ) ; dfsClient . metrics . incPreadSize ( realLen ) ; dfsClient . metrics . incPreadOps ( ) ; return realLen ; }
Read bytes starting from the specified position .