Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon s3 AmazonS3:获取警告:S3AbortableInputStream:没有从S3ObjectInputStream读取所有字节,正在中止HTTP连接_Amazon S3_Aws Sdk_Aws Java Sdk - Fatal编程技术网

Amazon s3 AmazonS3:获取警告:S3AbortableInputStream:没有从S3ObjectInputStream读取所有字节,正在中止HTTP连接

Amazon s3 AmazonS3:获取警告:S3AbortableInputStream:没有从S3ObjectInputStream读取所有字节,正在中止HTTP连接,amazon-s3,aws-sdk,aws-java-sdk,Amazon S3,Aws Sdk,Aws Java Sdk,以下是我得到的警告: S3AbortableInputStream:并非所有字节都从S3ObjectInputStream读取,正在中止HTTP连接。这可能是一个错误,并可能导致次优行为。使用后,通过远程获取或清空输入流,仅请求所需的字节 我尝试使用try with resources,但S3ObjectInputStream似乎无法通过此方法关闭 try (S3Object s3object = s3Client.getObject(new GetObjectRequest(bucket,

以下是我得到的警告:

S3AbortableInputStream:并非所有字节都从S3ObjectInputStream读取,正在中止HTTP连接。这可能是一个错误,并可能导致次优行为。使用后,通过远程获取或清空输入流,仅请求所需的字节

我尝试使用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
 }
我还尝试了以下代码并显式关闭,但也不起作用:

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中读取了两行文件,该文件包含更多数据。

通过其他媒体获得了答案。在这里分享:

警告表示您调用close()时没有读取整个文件。这是有问题的,因为S3仍在尝试发送数据,而您将使连接处于一种糟糕的状态

这里有两个选项:

  • 从输入流中读取其余数据,以便可以重用连接
  • 调用s3ObjectInputStream.abort()关闭连接而不读取数据。该连接不会被重用,因此在下一个重新创建连接的请求中会受到一些性能影响。如果要花很长时间来读取文件的其余部分,那么这可能是值得的

  • 为了给Chirag Sejpal的答案添加一个示例(详细说明选项1),可以使用以下内容在关闭输入流之前从输入流读取其余数据:

    S3Object S3Object=s3Client.getObject(新的GetObjectRequest(bucket,key));
    尝试(S3ObjectInputStream S3ObjectInputStream=s3object.getObjectContent()){
    试一试{
    //根据需要从流中读取
    }捕获(例外e){
    //根据需要处理异常
    }最后{
    while(s3ObjectInputStream!=null&&s3ObjectInputStream.read()!=-1){
    //阅读流的其余部分
    }
    }
    //try with resources语句将自动关闭流
    }
    
    我遇到了同样的错误

    正如其他人指出的,lambda中的/tmp空间被限制为512 MB。 如果lambda上下文被重新用于新的调用,那么/tmp空间已经满了一半

    因此,当读取S3对象并将所有文件写入/tmp目录时(正如我所做的那样), 我在两者之间的某个地方用完了磁盘空间。 Lambda退出时出错,但并不是从S3ObjectInputStream读取所有字节

    TransferManager transferManagerClient = TransferManagerBuilder.standard()
                    .withS3Client(amazonS3Client)
                    .build();
    
    因此,我们需要记住两件事:

    1) 如果第一次执行导致了问题,请谨慎使用/tmp空间。 我们只有512MB

    2) 如果第二次执行导致问题,那么可以通过攻击根问题来解决。 无法删除/tmp文件夹。 因此,在执行完成后删除/tmp文件夹中的所有文件

    在java中,我所做的就是成功地解决了这个问题

    publicstringhandlerequest(映射keyValuePairs,Context lambdaContext){
    试一试{
    //都在这里工作
    }捕获(例外e){
    error(“error{}”,例如toString());
    返回“错误”;
    }最后{
    deleteAllFilesInTmpDir();
    }
    }
    私有void deleteAllFilesInTmpDir(){
    Path Path=java.nio.file.Path.get(file.separator,“tmp”,file.separator);
    试一试{
    if(Files.exists(path)){
    deleteDir(path.toFile());
    info(“已成功清除tmp目录”);
    }
    }捕获(例外情况除外){
    logger.error(“无法清理tmp目录”);
    }
    }
    公共无效删除目录(文件目录){
    File[]files=dir.listFiles();
    如果(文件!=null){
    用于(最终文件:文件){
    deleteDir(文件);
    }
    }
    dir.delete();
    
    }
    我遇到了同样的问题,下面的课程帮助了我

    @Data
    @AllArgsConstructor
    public class S3ObjectClosable implements Closeable {
        private final S3Object s3Object;
    
        @Override
        public void close() throws IOException {
            s3Object.getObjectContent().abort();
            s3Object.close();
        }
    }
    
    现在,您可以在没有警告的情况下使用

    try (final var s3ObjectClosable = new S3ObjectClosable(s3Client.getObject(bucket, key))) {
    
    //same code
    
    }
    
    
    以下是Chirag Sejpal回答中的选项#1,我使用以下语句排出S3AbortableInputStream,以确保连接可以重用:

    com.amazonaws.util.IOUtils.drainInputStream(s3ObjectInputStream);
     
    

    这是我的解决方案。我使用的是SpringBoot2.4.3

    创建一个亚马逊s3客户端

    AmazonS3 amazonS3Client = AmazonS3ClientBuilder
                    .standard()
                    .withRegion("your-region")
                    .withCredentials(
                            new AWSStaticCredentialsProvider(
                                new BasicAWSCredentials("your-access-key", "your-secret-access-key")))
                    .build();
    
    // Note that in this line the s3 file downloaded has been transferred in to the temporary file that we created
    Download download = transferManagerClient.download(
                   new GetObjectRequest("your-s3-bucket-name", "your-s3-key"), file); 
    
    // This line blocks the thread until the download is finished
    download.waitForCompletion();  
    
    
    创建一个亚马逊传输客户端

    TransferManager transferManagerClient = TransferManagerBuilder.standard()
                    .withS3Client(amazonS3Client)
                    .build();
    
    /tmp/{your-s3-key}中创建一个临时文件,以便我们可以将下载的文件放入该文件中

    File file = new File(System.getProperty("java.io.tmpdir"), "your-s3-key"); 
    
    try {
        file.createNewFile(); // Create temporary file
    } catch (IOException e) {
        e.printStackTrace();
    }
    
    file.mkdirs();  // Create the directory of the temporary file
    
    然后,我们使用transfer manager客户端从s3下载文件

    AmazonS3 amazonS3Client = AmazonS3ClientBuilder
                    .standard()
                    .withRegion("your-region")
                    .withCredentials(
                            new AWSStaticCredentialsProvider(
                                new BasicAWSCredentials("your-access-key", "your-secret-access-key")))
                    .build();
    
    // Note that in this line the s3 file downloaded has been transferred in to the temporary file that we created
    Download download = transferManagerClient.download(
                   new GetObjectRequest("your-s3-bucket-name", "your-s3-key"), file); 
    
    // This line blocks the thread until the download is finished
    download.waitForCompletion();  
    
    
    现在,s3文件已成功传输到我们创建的临时文件中。我们可以获取临时文件的输入流

    因为临时文件不再需要了,我们只是删除它

    file.delete();
    

    “连接可以重用”是什么意思?我认为每个S3 GET-requestHi-Chirag都会创建一个HTTP连接,您能详细说明一下第1点吗(从输入流读取其余的数据,以便可以重用连接)?我的行是这样的:S3ObjectInputStream targetStream=confige.getObjectContent();XSSF工作簿excelf=新XSSF工作簿(targetStream);不确定如何抑制此警告。@ares SDK在后台维护一个连接池,可以为后续请求重新使用连接以获得更好的性能。如果在
    //必要时从流中读取时引发异常,我认为这不起作用part@sworisbreathing我已经更新了这个例子,所以剩下的即使在
    //根据需要从流中读取
    部分期间出现异常,也会读取流的,它显示
    java.io.IOException:trusted read on closed stream
    此try with resources代码样式将不起作用,因为资源将在执行
    catch
    finally
    块之前关闭。因此,要使代码正常工作,您必须切换回旧式
    try
    /
    catch
    /
    finally
    块,手动关闭
    finally
    b