当我将 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读取的方法。还有其他选择吗?
最佳答案
经过一些研究,这是我发现的:
- InputStream 本质上是阻塞的,因此当您从输入流读取时,某些线程将被阻塞,以防 @jakobeha's回答'toByteReadChannel ' 将返回一个读阻塞 channel 。因此,考虑到性能,它在某种程度上相当于在后台线程中执行同步 S3Client.fromInputStream(),您可以通过将其包装在 CompletableFuture 中来做到这一点。
- 其他“AsyncRequestBody”类型(例如“FileAsyncRequestBody”)使用带回调的“nio”(非阻塞 I/O)。也许这就是为什么AWS团队没有在“AsyncRequestBody”中包含“fromInputStream”,因为根本不可能使用完全非阻塞的方式,而且会引起困惑。
- 如果您想要一个高度可扩展的解决方案,最好的解决方案是不要一起使用InputStream,找到InputStream的起源并使用一些支持非阻塞 channel 的替代方案,在我的例子中,我使用了Java Flow并将其转换到“Publisher”并使用 AsyncRequestBody.fromPublisher()
关于java - 使用适用于 Java 的 AWS 开发工具包版本 2 将 InputStream 异步(非阻塞)上传到 AWS s3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67476133/