AmazonS3: Получение предупреждения: S3AbortableInputStream: не все байты были прочитаны из S3ObjectInputStream, прерывая HTTP-соединение

Вот предупреждение, которое я получаю:

S3AbortableInputStream: не все байты были прочитаны из S3ObjectInputStream, прерывая HTTP-соединение. Вероятно, это ошибка и может привести к субоптимальному поведению. Запросите только байты, которые вам понадобятся, через GET Ranged или слейте входной поток после использования.

Я попытался использовать try с ресурсами, но S3ObjectInputStream, похоже, не закрывается с помощью этого метода.

 try (S3Object s3object = s3Client.getObject(new GetObjectRequest(bucket, key));
      S3ObjectInputStream s3ObjectInputStream = s3object.getObjectContent();
      BufferedReader reader = new BufferedReader(new InputStreamReader(s3ObjectInputStream, StandardCharsets.UTF_8));
    ){
  //some code here blah blah blah
 }

Я также пробовал код ниже и явно закрываю, но это тоже не работает:

S3Object s3object = s3Client.getObject(new GetObjectRequest(bucket, key));
S3ObjectInputStream s3ObjectInputStream = s3object.getObjectContent();

try (BufferedReader reader = new BufferedReader(new InputStreamReader(s3ObjectInputStream, StandardCharsets.UTF_8));
){
     //some code here blah blah
     s3ObjectInputStream.close();
     s3object.close();
}

Любая помощь будет оценена.

PS: Я только читаю две строки файла из S3, и файл имеет больше данных.

Ответ 1

Получил ответ через другую среду. Разделите его здесь:

Предупреждение указывает, что вы вызвали close(), не читая весь файл. Это проблематично, потому что S3 все еще пытается отправить данные, и вы покидаете соединение в печальном состоянии.

Здесь есть два варианта:

  • Прочитайте остальную часть данных из входного потока, чтобы соединение можно было повторно использовать.
  • Вызовите s3ObjectInputStream.abort(), чтобы закрыть соединение, не читая данные. Соединение не будет использоваться повторно, поэтому вы получите некоторое повышение производительности при следующем запросе на повторное создание соединения. Это может стоить того, если потребуется много времени, чтобы прочитать остальную часть файла.

Ответ 2

Чтобы добавить пример к ответу Chirag Sejpal (подробно остановившись на опции # 1), можно использовать следующее, чтобы прочитать остальные данные из входного потока перед его закрытием:

S3Object s3object = s3Client.getObject(new GetObjectRequest(bucket, key));

try (S3ObjectInputStream s3ObjectInputStream = s3object.getObjectContent()) {
  try {
    // Read from stream as necessary
  } catch (Exception e) {
    // Handle exceptions as necessary
  } finally {
    while (s3ObjectInputStream != null && s3ObjectInputStream.read() != -1) {
      // Read the rest of the stream
    }
  }

  // The stream will be closed automatically by the try-with-resources statement
}