java使用TransferManager将大文件上传到AmazonS3存储桶的最佳方法
目前,我正在尝试将一个文件上载到AmazonS3存储桶,我对此进行了一些研究,发现如果文件足够大,类TransferManager会将文件拆分为小块,然后使用多个线程并行上载。现在在应用程序中,我们正在创建一个AmazonS3客户端实例(在应用程序开始时创建的一个bean),并使用该AmazonS3客户端为用户上传文件所需的每个文件创建TransferManager类实例,文件上传完成后(由TransferManager的waitForCompletion方法检查),我们将调用TransferManager方法。shutdownNow(false)关闭它创建的所有线程,如下所示:
@AutoWired
private AmazonS3 s3Client;
/**
* Uploads a file using TransferManager from a MultipartFile.
*/
public String uploadFileParallelized(MultipartFile file) {
String fileName;
TransferManager transferManager =
TransferManagerBuilder.standard().withS3Client(this.s3Client).build();
try {
String extension = getExtensionFromBytes(file.getBytes());
fileName = getFileName(extension);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(file.getSize());
metadata.setContentType(file.getContentType());
Upload upload = transferManager.upload(getBucketName(), this.folder + fileName,
file.getInputStream(), metadata);
upload.waitForCompletion();
} catch (IOException | AmazonClientException | InterruptedException e) {
throw new FileUploadException("Couldn't upload the file to S3: " + e.getLocalizedMessage(),
e);
} finally {
transferManager.shutdownNow(false);
}
return fileName;
}
我仍然有疑问:
我不确定您是应该为每次上传实例化transferManager,还是应该只使用transferManager的一个实例(可能是一个bean),但在这种情况下,我将无法调用transferManager。shutdownNow(false)方法,因为我无法将其用于第二次上载
即使我没有调用shutdownNow方法,TransferManager是否会关闭用于上载文件的所有线程
使用同一个AmazonS3客户端创建TransferManager的多个实例可以吗?还是应该为我们需要的每个TransferManager创建一个S3Client
即使文件很小(比如小于5 MB),我们是否也应该使用TransferManager
# 1 楼答案
https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/transfer/TransferManager.html
所有上传完成后,应该在单个
TransferManager
实例上调用shutdownNow
对
您应该使用相同的S3客户端。它是线程安全的
minUploadPartSize
是5MB,minUploadThresholdSize
是16MB。您可以对所有文件使用TransferManager
到upload
,它会根据文件大小对文件进行分解。这些选项是可配置的。如果您知道所有文件都相对较小,那么使用putObject
可能会更容易