code: private void reopenS3InputStream()
              throws IOException {
          // First attempt to close the existing input stream
          try {
              closeS3InputStream();
          } catch (IOException ignore) {
              // Ignore this exception; we're re-opening because there was in issue with the existing stream
              // in the first place.
          }
  
          InputStream remainingIn = null;
          int attempt = 0;
          while (remainingIn == null) {
              try {
                  S3Object s3Object = _s3.getObject(
                          new GetObjectRequest(_bucket, _key)
                                  .withRange(_pos, _length - 1));  // Range is inclusive, hence length-1
  
                  remainingIn = s3Object.getObjectContent();
              } catch (AmazonClientException e) {
                  // Allow up to 3 retries
                  attempt += 1;
                  if (!e.isRetryable() || attempt == 4) {
                      throw e;
                  }
                  // Back-off on each retry
                  try {
                      Thread.sleep(200 * attempt);
                  } catch (InterruptedException interrupt) {
                      throw Throwables.propagate(interrupt);
                  }
              }
          }
  
          _in = remainingIn;
      }
docs: Re-opens the input stream, starting at the first unread byte.