cdm/src/main/java/ucar/unidata/io/RandomAccessFile.java
public int readBytes(byte b[], int off, int len) throws IOException {

    // Check for end of file.
    if (endOfFile) {
      return -1;
    }

    // See how many bytes are available in the buffer - if none,
    // seek to the file position to update the buffer and try again.
    int bytesAvailable = (int) (dataEnd - filePosition);
    if (bytesAvailable < 1) {
      seek(filePosition);
      return readBytes(b, off, len);
    }

    // Copy as much as we can.
    int copyLength = (bytesAvailable >= len)
            ? len
            : bytesAvailable;
    System.arraycopy(buffer, (int) (filePosition - bufferStart), b, off, copyLength);
    filePosition += copyLength;

    // If there is more to copy...
    if (copyLength < len) {
      int extraCopy = len - copyLength;

      // If the amount remaining is more than a buffer's length, read it
      // directly from the file.
      if (extraCopy > buffer.length) {
        extraCopy = read_(filePosition, b, off + copyLength, len - copyLength);

        // ...or read a new buffer full, and copy as much as possible...
      } else {
        seek(filePosition);
        if (!endOfFile) {
          extraCopy = (extraCopy > dataSize)
                  ? dataSize
                  : extraCopy;
          System.arraycopy(buffer, 0, b, off + copyLength, extraCopy);
        } else {
          extraCopy = -1;
        }
      }

      // If we did manage to copy any more, update the file position and
      // return the amount copied.
      if (extraCopy > 0) {
        filePosition += extraCopy;
        return copyLength + extraCopy;
      }
    }

    // Return the amount copied.
    return copyLength;
  }
public int readBytes(byte b[], int off, int len) throws IOException {

    // Check for end of file.
    if (endOfFile) {
      return -1;
    }

    // See how many bytes are available in the buffer - if none,
    // seek to the file position to update the buffer and try again.
    int bytesAvailable = (int) (dataEnd - filePosition);
    if (bytesAvailable < 1) {
      seek(filePosition);
      return readBytes(b, off, len);
    }

    // Copy as much as we can.
    int copyLength = (bytesAvailable >= len)
            ? len
            : bytesAvailable;
    System.arraycopy(buffer, (int) (filePosition - bufferStart), b, off, copyLength);
    filePosition += copyLength;

    // If there is more to copy...
    if (copyLength < len) {
      int extraCopy = len - copyLength;

      // If the amount remaining is more than a buffer's length, read it
      // directly from the file.
      if (extraCopy > buffer.length) {
        extraCopy = read_(filePosition, b, off + copyLength, len - copyLength);

        // ...or read a new buffer full, and copy as much as possible...
      } else {
        seek(filePosition);
        if (!endOfFile) {
          extraCopy = (extraCopy > dataSize)
                  ? dataSize
                  : extraCopy;
          System.arraycopy(buffer, 0, b, off + copyLength, extraCopy);
        } else {
          extraCopy = -1;
        }
      }

      // If we did manage to copy any more, update the file position and
      // return the amount copied.
      if (extraCopy > 0) {
        filePosition += extraCopy;
        return copyLength + extraCopy;
      }
    }

    // Return the amount copied.
    return copyLength;
  }
Read up to <code>len</code> bytes into an array, at a specified
offset. This will block until at least one byte has been read.

@param b   the byte array to receive the bytes.
@param off the offset in the array where copying will start.
@param len the number of bytes to copy.
@return the actual number of bytes read, or -1 if there is not
more data due to the end of the file being reached.
@throws IOException if an I/O error occurrs.