code: public SelectRecordsInputStream getRecordsInputStream(SelectObjectContentEventVisitor listener)
              throws SelectObjectContentEventException {
          InputStream recordInputStream = new SequenceInputStream(new EventStreamEnumeration(getEventsIterator(), listener));
  
          // Ignore close() calls to the record stream. The sequence input stream would read the whole stream to close all of the
          // streams in the enum, and the streams in the enum aren't needed because they're byte array input streams.
          recordInputStream = ReleasableInputStream.wrap(recordInputStream).disableClose();
  
          return new SelectRecordsInputStream(recordInputStream, inputStream);
      }
docs: Retrieve an input stream to the subset of the S3 object that matched the query. This is equivalent to loading the content
  of all {@link SelectObjectContentEvent.RecordsEvent}s into an {@link InputStream}. This will lazily-load the content from
  S3, minimizing the amount of memory used.
  
  Unlike {@link #getRecordsInputStream()}, this allows you to provide a "listener" {@link SelectObjectContentEventVisitor}
  that intercepts the events returned by S3 while the thread that called {@link SelectRecordsInputStream#read()} blocks
  waiting for S3 to return a response.
  
  This will raise a runtime exception if {@link #getAllEvents()}, {@link #visitAllEvents(SelectObjectContentEventVisitor)}
  or {@link #getEventsIterator()} have already been used.
  
  Like all streams, you should {@link SelectRecordsInputStream#close()} it after the content has been read. This
  is equivalent to calling {@link #close()} on this {@link SelectObjectContentEventStream}.
  
  @param listener A visitor for monitoring the progress of the query between {@link RecordsEvent}s.
  @see #getRecordsInputStream()