@ Override public synchronized int read ( ByteBuffer dst ) throws IOException { if ( ! open ) { throw new ClosedChannelException ( ) ; } try { if ( trackTime ) { msBetweenCallsToRead += betweenCallsToRead . elapsed ( TimeUnit . MILLISECONDS ) ; } ByteBuffer src ; try { Stopwatch waitingForData ; if ( trackTime ) { waitingForData = Stopwatch . createStarted ( ) ; } src = fetch ( position ) ; if ( trackTime ) { msWaitingForData += waitingForData . elapsed ( TimeUnit . MILLISECONDS ) ; } } catch ( InterruptedException e ) { // Restore interrupted status Thread . currentThread ( ) . interrupt ( ) ; return 0 ; } catch ( ExecutionException e ) { throw new RuntimeException ( e ) ; } if ( null == src ) { // the caller is asking for a block past EOF nbReadsPastEnd ++ ; return - 1 ; // EOF } Stopwatch copyingData ; if ( trackTime ) { copyingData = Stopwatch . createStarted ( ) ; } // src.position is how far we've written into the array long blockIndex = position / bufSize ; int offset = ( int ) ( position - ( blockIndex * bufSize ) ) ; // src |==============---------------------| // :<---src.pos-->------src.limit----->: // |---:--position-> // :<--offset--> // ^ blockIndex*bufSize int availableToCopy = src . position ( ) - offset ; if ( availableToCopy < 0 ) { // the caller is asking to read past the end of the file nbReadsPastEnd ++ ; return - 1 ; // EOF } int bytesToCopy = dst . remaining ( ) ; byte [ ] array = src . array ( ) ; if ( availableToCopy < bytesToCopy ) { bytesToCopy = availableToCopy ; } dst . put ( array , offset , bytesToCopy ) ; position += bytesToCopy ; if ( trackTime ) { msCopyingData += copyingData . elapsed ( TimeUnit . MILLISECONDS ) ; } bytesReturned += bytesToCopy ; if ( availableToCopy == 0 ) { // EOF return - 1 ; } return bytesToCopy ; } finally { if ( trackTime ) { betweenCallsToRead . reset ( ) ; betweenCallsToRead . start ( ) ; } } }
Reads a sequence of bytes from this channel into the given buffer .