AmazonS3:获取警告:S3AbortableInputStream:并非所有字节都从S3ObjectInputStream读取,中止HTTP连接

Chi*_*pal 12 amazon-s3 aws-sdk aws-java-sdk

这是我得到的警告:

S3AbortableInputStream:并非所有字节都从S3ObjectInputStream中读取,从而中止HTTP连接.这可能是错误,可能导致次优行为.通过范围GET仅请求您需要的字节或在使用后消耗输入流.

我尝试使用try with resources但是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
 }
Run Code Online (Sandbox Code Playgroud)

我也试过下面的代码并明确关闭,但这也不起作用:

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();
}
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激.

PS:我只从S3读取两行文件,文件中有更多数据.

Chi*_*pal 18

通过其他媒介得到答案.在这里分享:

警告表示您在不读取整个文件的情况下调用了close().这是有问题的,因为S3仍在尝试发送数据,而您正在将连接置于悲伤状态.

这里有两个选项:

  1. 从输入流中读取其余数据,以便可以重用连接.
  2. 调用s3ObjectInputStream.abort()来关闭连接而不读取数据.连接将不会被重用,因此您可以在下一个重新创建连接请求时获得一些性能.如果需要很长时间才能阅读文件的其余部分,这可能是值得的.

  • 你是什​​么意思 - “连接可以重用”?我认为每个 S3 GET 请求都会创建一个 HTTP 连接 (2认同)
  • @ares SDK 在幕后维护了一个连接池,可以为后续请求重用连接以获得更好的性能。 (2认同)

小智 6

根据 Chirag Sejpal 的答案的选项#1,我使用以下语句来耗尽 S3AbortableInputStream 以确保可以重用连接:

com.amazonaws.util.IOUtils.drainInputStream(s3ObjectInputStream);
 
Run Code Online (Sandbox Code Playgroud)