View a markdown version of this page

使用 Amazon SDK 将未知大小的流上传到 Amazon S3 对象 - Amazon Simple Storage Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用 Amazon SDK 将未知大小的流上传到 Amazon S3 对象

下面的代码示例演示了如何将未知大小的流上传到 Amazon S3 对象。

Java
适用于 Java 的 SDK 2.x
注意

查看 GitHub,了解更多信息。在 Amazon 代码示例存储库中查找完整示例,了解如何进行设置和运行。

使用 Amazon 基于 CRT 的 S3 客户端

import com.example.s3.util.AsyncExampleUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.core.exception.SdkException; import software.amazon.awssdk.services.s3.S3AsyncClient; import software.amazon.awssdk.services.s3.model.PutObjectResponse; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class PutObjectFromStreamAsync { private static final Logger logger = LoggerFactory.getLogger(PutObjectFromStreamAsync.class); public static void main(String[] args) { String bucketName = "amzn-s3-demo-bucket"; // Replace with your bucket name. String key = UUID.randomUUID().toString(); AsyncExampleUtils.createBucket(bucketName); try { PutObjectFromStreamAsync example = new PutObjectFromStreamAsync(); S3AsyncClient s3AsyncClientCrt = S3AsyncClient.crtCreate(); PutObjectResponse putObjectResponse = example.putObjectFromStreamCrt(s3AsyncClientCrt, bucketName, key); logger.info("Object {} etag: {}", key, putObjectResponse.eTag()); logger.info("Object {} uploaded to bucket {}.", key, bucketName); } catch (SdkException e) { logger.error(e.getMessage(), e); } finally { AsyncExampleUtils.deleteObject(bucketName, key); AsyncExampleUtils.deleteBucket(bucketName); } } /** * @param s33CrtAsyncClient - To upload content from a stream of unknown size, use can the AWS CRT-based S3 client. * @param bucketName - The name of the bucket. * @param key - The name of the object. * @return software.amazon.awssdk.services.s3.model.PutObjectResponse - Returns metadata pertaining to the put object operation. */ public PutObjectResponse putObjectFromStreamCrt(S3AsyncClient s33CrtAsyncClient, String bucketName, String key) { // AsyncExampleUtils.randomString() returns a random string up to 100 characters. String randomString = AsyncExampleUtils.randomString(); logger.info("random string to upload: {}: length={}", randomString, randomString.length()); InputStream inputStream = new ByteArrayInputStream(randomString.getBytes()); // Executor required to handle reading from the InputStream on a separate thread so the main upload is not blocked. ExecutorService executor = Executors.newSingleThreadExecutor(); // Specify `null` for the content length when you don't know the content length. AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor); CompletableFuture<PutObjectResponse> responseFuture = s33CrtAsyncClient.putObject(r -> r.bucket(bucketName).key(key), body); PutObjectResponse response = responseFuture.join(); // Wait for the response. logger.info("Object {} uploaded to bucket {}.", key, bucketName); executor.shutdown(); return response; } }

使用标准的启用了分段上传的异步 S3 客户端

import com.example.s3.util.AsyncExampleUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.core.exception.SdkException; import software.amazon.awssdk.services.s3.S3AsyncClient; import software.amazon.awssdk.services.s3.model.PutObjectResponse; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class PutObjectFromStreamAsyncMp { private static final Logger logger = LoggerFactory.getLogger(PutObjectFromStreamAsyncMp.class); public static void main(String[] args) { String bucketName = "amzn-s3-demo-bucket"; // Replace with your bucket name. String key = UUID.randomUUID().toString(); AsyncExampleUtils.createBucket(bucketName); try { PutObjectFromStreamAsyncMp example = new PutObjectFromStreamAsyncMp(); S3AsyncClient s3AsyncClientMp = S3AsyncClient.builder().multipartEnabled(true).build(); PutObjectResponse putObjectResponse = example.putObjectFromStreamMp(s3AsyncClientMp, bucketName, key); logger.info("Object {} etag: {}", key, putObjectResponse.eTag()); logger.info("Object {} uploaded to bucket {}.", key, bucketName); } catch (SdkException e) { logger.error(e.getMessage(), e); } finally { AsyncExampleUtils.deleteObject(bucketName, key); AsyncExampleUtils.deleteBucket(bucketName); } } /** * @param s3AsyncClientMp - To upload content from a stream of unknown size, use can the S3 asynchronous client with multipart enabled. * @param bucketName - The name of the bucket. * @param key - The name of the object. * @return software.amazon.awssdk.services.s3.model.PutObjectResponse - Returns metadata pertaining to the put object operation. */ public PutObjectResponse putObjectFromStreamMp(S3AsyncClient s3AsyncClientMp, String bucketName, String key) { // AsyncExampleUtils.randomString() returns a random string up to 100 characters. String randomString = AsyncExampleUtils.randomString(); logger.info("random string to upload: {}: length={}", randomString, randomString.length()); InputStream inputStream = new ByteArrayInputStream(randomString.getBytes()); // Executor required to handle reading from the InputStream on a separate thread so the main upload is not blocked. ExecutorService executor = Executors.newSingleThreadExecutor(); // Specify `null` for the content length when you don't know the content length. AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor); CompletableFuture<PutObjectResponse> responseFuture = s3AsyncClientMp.putObject(r -> r.bucket(bucketName).key(key), body); PutObjectResponse response = responseFuture.join(); // Wait for the response. logger.info("Object {} uploaded to bucket {}.", key, bucketName); executor.shutdown(); return response; } }

使用 Amazon S3 Transfer Manager

import com.example.s3.util.AsyncExampleUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.core.exception.SdkException; import software.amazon.awssdk.transfer.s3.S3TransferManager; import software.amazon.awssdk.transfer.s3.model.CompletedUpload; import software.amazon.awssdk.transfer.s3.model.Upload; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class UploadStream { private static final Logger logger = LoggerFactory.getLogger(UploadStream.class); public static void main(String[] args) { String bucketName = "amzn-s3-demo-bucket"; // Replace with your bucket name. String key = UUID.randomUUID().toString(); AsyncExampleUtils.createBucket(bucketName); try { UploadStream example = new UploadStream(); CompletedUpload completedUpload = example.uploadStream(S3TransferManager.create(), bucketName, key); logger.info("Object {} etag: {}", key, completedUpload.response().eTag()); logger.info("Object {} uploaded to bucket {}.", key, bucketName); } catch (SdkException e) { logger.error(e.getMessage(), e); } finally { AsyncExampleUtils.deleteObject(bucketName, key); AsyncExampleUtils.deleteBucket(bucketName); } } /** * @param transferManager - To upload content from a stream of unknown size, you can use the S3TransferManager based on the AWS CRT-based S3 client. * @param bucketName - The name of the bucket. * @param key - The name of the object. * @return - software.amazon.awssdk.transfer.s3.model.CompletedUpload - The result of the completed upload. */ public CompletedUpload uploadStream(S3TransferManager transferManager, String bucketName, String key) { // AsyncExampleUtils.randomString() returns a random string up to 100 characters. String randomString = AsyncExampleUtils.randomString(); logger.info("random string to upload: {}: length={}", randomString, randomString.length()); InputStream inputStream = new ByteArrayInputStream(randomString.getBytes()); // Executor required to handle reading from the InputStream on a separate thread so the main upload is not blocked. ExecutorService executor = Executors.newSingleThreadExecutor(); // Specify `null` for the content length when you don't know the content length. AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor); Upload upload = transferManager.upload(builder -> builder .requestBody(body) .putObjectRequest(req -> req.bucket(bucketName).key(key)) .build()); CompletedUpload completedUpload = upload.completionFuture().join(); executor.shutdown(); return completedUpload; } }
Swift
适用于 Swift 的 SDK
注意

查看 GitHub,了解更多信息。在 Amazon 代码示例存储库中查找完整示例,了解如何进行设置和运行。

import ArgumentParser import AWSClientRuntime import AWSS3 import Foundation import Smithy import SmithyHTTPAPI import SmithyStreams /// Upload a file to the specified bucket. /// /// - Parameters: /// - bucket: The Amazon S3 bucket name to store the file into. /// - key: The name (or path) of the file to upload to in the `bucket`. /// - sourcePath: The pathname on the local filesystem of the file to /// upload. func uploadFile(sourcePath: String, bucket: String, key: String?) async throws { let fileURL: URL = URL(fileURLWithPath: sourcePath) let fileName: String // If no key was provided, use the last component of the filename. if key == nil { fileName = fileURL.lastPathComponent } else { fileName = key! } let s3Client = try await S3Client() // Create a FileHandle for the source file. let fileHandle = FileHandle(forReadingAtPath: sourcePath) guard let fileHandle = fileHandle else { throw TransferError.readError } // Create a byte stream to retrieve the file's contents. This uses the // Smithy FileStream and ByteStream types. let stream = FileStream(fileHandle: fileHandle) let body = ByteStream.stream(stream) // Create a `PutObjectInput` with the ByteStream as the body of the // request's data. The AWS SDK for Swift will handle sending the // entire file in chunks, regardless of its size. let putInput = PutObjectInput( body: body, bucket: bucket, key: fileName ) do { _ = try await s3Client.putObject(input: putInput) } catch { throw TransferError.uploadError("Error uploading the file: \(error)") } print("File uploaded to \(fileURL.path).") }

有关 Amazon SDK 开发人员指南和代码示例的完整列表,请参阅 使用 Amazon SDK 通过 Amazon S3 进行开发。本主题还包括有关入门的信息以及有关先前的 SDK 版本的详细信息。