使用适用于 Java 的 AWS 开发工具包版本 2 从 URL 下载文件并将其上传到 AWS S3,无需保存到内存中

Ket*_*ari 5 java inputstream amazon-s3 amazon-web-services aws-sdk

我正在编写一个代码,将从 URL 下载文件并将其上传到 S3,但我不希望将其临时存储在文件或内存中,我正在通过“InputStream”下载,但 AWS s3 需要我的文件大小没有来自“InputStream”的还有其他方法吗? 我使用“Node.js”找到了关于同一主题的讨论


我的代码在 inputStream 中获取文件


HttpClient client = HttpClient.newBuilder().build();
URI uri = URI.create("{myUrl}");
HttpRequest request = HttpRequest.newBuilder().uri(uri).build();
InputStream is = client.send(request, HttpResponse.BodyHandlers.ofInputStream()).body();
Run Code Online (Sandbox Code Playgroud)

我尝试插入 S3 的代码,但没有 content_length


S3Client s3Client = S3Client.builder().build();
PutObjectRequest objectRequest = PutObjectRequest.builder()
                            .bucket(BUCKET_NAME)
                            .key(KEY)
                            .build();

PutObjectResponse por = s3Client.putObject(objectRequest, RequestBody.fromInputStream(is,content_length));

Run Code Online (Sandbox Code Playgroud)

Par*_*fal 1

你有几个选择。

最简单的方法是保留HttpResponse中的client.send(),并Content-Length从中获取标头。您还应该寻找诸如 之类的标头Content-Type,并将它们作为元数据存储在 S3 对象上。

这并不能保证在所有情况下都有效:某些服务器不提供Content-Length. 在这种情况下,您需要创建分段上传来发送文件。执行此操作时,您可以在内存中缓冲相对较小的块(最小 5 MB),但最多可以上传 10,000 个块。您必须完成或中止上传,或者将您的存储桶配置为在一段时间后删除未完成的上传;否则,您将因上传不完整而被收取费用。

第三种选择是使用 V1 SDK,它为您提供TransferManager. 它可以为您处理分段上传,并使用多个线程来提高带宽。但 V2 尚未实现。