code: @Override
    public synchronized int read(byte[] buf, int off, int len)
        throws IOException {
      checkNotClosed();
  
      validatePositionedReadArgs(nextReadPos, buf, off, len);
      if (len == 0) {
        return 0;
      }
  
      if (contentLength == 0 || (nextReadPos >= contentLength)) {
        return -1;
      }
  
      try {
        lazySeek(nextReadPos, len);
      } catch (EOFException e) {
        // the end of the file has moved
        return -1;
      }
  
      int bytesRead;
      try {
        bytesRead = wrappedStream.read(buf, off, len);
      } catch (EOFException e) {
        onReadFailure(e, len);
        // the base implementation swallows EOFs.
        return -1;
      } catch (IOException e) {
        onReadFailure(e, len);
        bytesRead = wrappedStream.read(buf, off, len);
      }
  
      if (bytesRead > 0) {
        pos += bytesRead;
        nextReadPos += bytesRead;
      }
      incrementBytesRead(bytesRead);
      return bytesRead;
    }
docs: {@inheritDoc}
  
  This updates the statistics on read operations started and whether
  or not the read operation "completed", that is: returned the exact
  number of bytes requested.
  @throws IOException if there are other problems