java - 使用适用于 Java 的 AWS 开发工具包版本 2 将 InputStream 异步(非阻塞)上传到 AWS s3

标签 java amazon-web-services asynchronous amazon-s3 aws-sdk

当我将 inputStream 对象同步上传到 s3(阻塞方式)时,它可以工作。

S3Client s3Client = S3Client.builder().build();
s3Client.putObject(objectRequest, RequestBody.fromInputStream(inputStream,STREAM_SIZE));

但是当我尝试使用 S3AsyncClient 进行相同操作时,AsyncRequestBody 上没有 .fromInputStream 方法。

S3AsyncClient s3AsyncClient = S3AsyncClient.builder().build();
s3AsyncClient.putObject(objectRequest, AsyncRequestBody.fromInputStream(inputStream,STREAM_SIZE)); // error no method named 'fromInputStream'

而且我不能使用 .fromByteBuffer 因为它会将整个流加载到内存中,这是我不想要的。

我很感兴趣为什么AsyncRequestBody中没有从InputStream读取的方法。还有其他选择吗?

最佳答案

经过一些研究,这是我发现的:

  1. InputStream 本质上是阻塞的,因此当您从输入流读取时,某些线程将被阻塞,以防 @jakobeha's回答'toByteReadChannel ' 将返回一个读阻塞 channel 。因此,考虑到性能,它在某种程度上相当于在后台线程中执行同步 S3Client.fromInputStream(),您可以通过将其包装在 CompletableFuture 中来做到这一点。
  2. 其他“AsyncRequestBody”类型(例如“FileAsyncRequestBody”)使用带回调的“nio”(非阻塞 I/O)。也许这就是为什么AWS团队没有在“AsyncRequestBody”中包含“fromInputStream”,因为根本不可能使用完全非阻塞的方式,而且会引起困惑。
  3. 如果您想要一个高度可扩展的解决方案,最好的解决方案是不要一起使用InputStream,找到InputStream的起源并使用一些支持非阻塞 channel 的替代方案,在我的例子中,我使用了Java Flow并将其转换到“Publisher”并使用 AsyncRequestBody.fromPublisher()

关于java - 使用适用于 Java 的 AWS 开发工具包版本 2 将 InputStream 异步(非阻塞)上传到 AWS s3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67476133/

相关文章:

java - 无循环选择排序

javascript - 如何从 Android Java 中无延迟地调用 WebView Javascript 中的函数?

java - 使用 GXT RPCMAP 序列化异常

java - 与 AWS CLI 和 Java SDK 不同的 SQS 队列 URL

C++ Ubuntu select() 如果串行接口(interface)有数据异步读取

c# - 结构的私有(private)字段值未使用异步方法更新

java - 无法访问另一个类的方法

amazon-web-services - AWS Cognito 使用别名登录

json - 如何使用代理 Lambda 从 API Gateway 发送多个 Set-Cookie header

javascript - Node 在执行代码之前等待所有异步调用