Java Awssdk S3 Tải object xuống với S3TransferManager
S3TransferManager là một tiện ích truyền tải cấp cao được xây dựng dựa trên S3Client. Nó cung cấp một API đơn giản để cho phép bạn truyền tệp và thư mục giữa ứng dụng của bạn và Amazon S3.
S3TransferManager cũng cho phép bạn theo dõi tiến trình truyền trong thời gian thực cũng như tạm dừng quá trình truyền để thực hiện sau đó.
MyUtils.java (*)
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.SizeConstant;
public class MyUtils {
public static S3TransferManager createS3TransferManager(Region region) {
AwsCredentials credentials = AwsBasicCredentials.create("accessKeyId", "secretAccessKey");
AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(credentials);
S3AsyncClient s3AsyncClient = S3AsyncClient.crtBuilder() //
.credentialsProvider(credentialsProvider) //
.region(region) //
.targetThroughputInGbps(20.0) //
.minimumPartSizeInBytes(10 * SizeConstant.MB) //
.build();
return S3TransferManager.builder().s3Client(s3AsyncClient).build();
}
}
Để tạo đối tượng S3TransferManager bạn cần phải tạo một đối tượng AwsCredentialsProvider, đối tượng này cung cấp thông tin xác thực (Credentials) cho phép bạn tương tác với AWS. Xem thêm bài viết dưới đây để tạo một AwsCredentialsProvider phù hợp với mục đích sử dụng của bạn.
1. Thư viện
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk/s3 -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.21.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk/s3-transfer-manager -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3-transfer-manager</artifactId>
<version>2.21.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk.crt/aws-crt -->
<dependency>
<groupId>software.amazon.awssdk.crt</groupId>
<artifactId>aws-crt</artifactId>
<version>0.28.0</version>
</dependency>
<!-- Log Library -->
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<!-- Log Library -->
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.9</version>
</dependency>
2. Download một file
Một ví dụ đơn giản sử dụng S3TransferManager download một file từ S3 Bucket về máy tính địa phương của bạn.
DownloadOneFileExample1.java
package org.o7planning.java_14249_awssdk_s3;
import java.nio.file.Paths;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletionException;
import org.o7planning.java_14249_awssdk_s3.utils.MyUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedFileDownload;
import software.amazon.awssdk.transfer.s3.model.DownloadFileRequest;
import software.amazon.awssdk.transfer.s3.model.FileDownload;
import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener;
public class DownloadOneFileExample1 {
private static final Region MY_BUCKET_REGION = Region.EU_CENTRAL_1;
private static final String BUCKET_NAME = "my-bucket-name";
public static void downloadFile(S3TransferManager transferManager, String bucketName, //
String key, String filePath) {
DownloadFileRequest downloadFileRequest = DownloadFileRequest.builder()
.getObjectRequest(req -> req.bucket(bucketName).key(key)) // bucketName & key
.destination(Paths.get(filePath))
// Attaching a LoggingTransferListener that will log the progress
.addTransferListener(LoggingTransferListener.create()).build();
FileDownload fileDownload = transferManager.downloadFile(downloadFileRequest);
try {
// Wait for the transfer to complete
CompletedFileDownload completedFileDownload = fileDownload //
.completionFuture() // CompletableFuture<CompletedFileDownload>
.join(); // Wait until completed, and return value.
//
System.out.println("SuccessfullyCompleted");
System.out.println(" --> " + completedFileDownload.toString());
} catch (CancellationException e) {
System.out.println("CancellationException");
System.out.println(" --> (It could be by the user calling the pause method.)");
} catch (CompletionException e) {
System.out.println("Completed with error: " + e);
}
}
public static void main(String[] args) {
// There are several ways to create an S3TransferManager
// @See my article 14231.
S3TransferManager transferManager = MyUtils.createS3TransferManager(MY_BUCKET_REGION);
//
// Test download a video file 11.9MB
//
downloadFile(transferManager, //
BUCKET_NAME, // bucketName
"static/videos/sample-15s.mp4", // key
"/Volumes/New/Test/download/sample-15s.mp4" // filePath to save.
);
}
}
Output:
[main] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - Transfer initiated...
[AwsEventLoop 12] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - |================= | 87.9%
[Thread-1] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - |====================| 100.0%
SuccessfullyCompleted
--> CompletedFileDownload(response=GetObjectResponse(AcceptRanges=bytes, LastModified=2023-11-02T18:54:31Z, ContentLength=11916526, ETag="3a1a600c79846a4af23e4eaeb62d4f77-2", ChecksumCRC32=owx0EQ==-2, ContentType=application/octet-stream, ServerSideEncryption=AES256, Metadata={}))
[sdk-async-response-0-0] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - Transfer complete!
3. Download nhiều file
Ví dụ đơn giản sử dụng S3TransferManager download nhiều file với tiếp đầu ngữ được chỉ định.
DownloadMultiFilesExample1.java
package org.o7planning.java_14249_awssdk_s3;
import java.nio.file.Paths;
import org.o7planning.java_14249_awssdk_s3.utils.MyUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedDirectoryDownload;
import software.amazon.awssdk.transfer.s3.model.DirectoryDownload;
import software.amazon.awssdk.transfer.s3.model.DownloadDirectoryRequest;
import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener;
public class DownloadMultiFilesExample1 {
private static final Region MY_BUCKET_REGION = Region.EU_CENTRAL_1;
private static final String BUCKET_NAME = "my-bucket-name";
public static Integer downloadMultiFiles(S3TransferManager transferManager, //
String bucketName, String keyPrefix, String destinationDirectory) {
// Create DownloadDirectoryRequest
DownloadDirectoryRequest downloadDirectoryRequest = DownloadDirectoryRequest.builder() //
.destination(Paths.get(destinationDirectory))//
.bucket(bucketName) //
// Only download objects with prefix
.listObjectsV2RequestTransformer(l -> l.prefix(keyPrefix)) //
// Optional, add LoggingTransferListener for each file download.
.downloadFileRequestTransformer(
request -> request.addTransferListener(LoggingTransferListener.create()))
.build();
DirectoryDownload directoryDownload = transferManager.downloadDirectory(downloadDirectoryRequest);
// Wait for the transfer to complete
CompletedDirectoryDownload completedDirectoryDownload = directoryDownload //
.completionFuture() // CompletableFuture<CompletedFileDownload>
.join(); // Wait until completed, and return value.
// Print out any failed downloads
completedDirectoryDownload.failedTransfers().forEach(System.err::println);
return completedDirectoryDownload.failedTransfers().size();
}
public static void main(String[] args) {
// There are several ways to create an S3TransferManager
// @See my article 14231.
S3TransferManager transferManager = MyUtils.createS3TransferManager(MY_BUCKET_REGION);
//
// Test download all files with keyPrefix:
//
int failCount = downloadMultiFiles(transferManager, //
BUCKET_NAME, // bucketName
"static/images/", // keyPrefix
"/Volumes/New/Test/download/" // destinationDirectory
);
System.out.println("failCount: " + failCount);
}
}
Output:
[sdk-async-response-0-0] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - Transfer initiated...
[sdk-async-response-0-0] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - Transfer initiated...
[AwsEventLoop 8] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - |====================| 100.0%
[sdk-async-response-0-1] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - Transfer complete!
[AwsEventLoop 6] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - |====================| 100.0%
[sdk-async-response-0-2] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - Transfer complete!
failCount: 0
4. Download với tính năng pause/resume
Ví dụ, download một file với S3TransferManager và tính năng pause/resume (tạm dừng và tiếp tục lại).
ResumableFileDownloadThread.java
package org.o7planning.java_14249_awssdk_s3;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletionException;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedFileDownload;
import software.amazon.awssdk.transfer.s3.model.FileDownload;
import software.amazon.awssdk.transfer.s3.model.ResumableFileDownload;
import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener;
import software.amazon.awssdk.transfer.s3.model.DownloadFileRequest;
public class ResumableFileDownloadThread extends Thread {
private S3TransferManager transferManager;
private String bucketName;
private String key;
private String filePath;
private FileDownload fileDownload;
private boolean isPause;
private boolean successfullyCompleted;
public ResumableFileDownloadThread(S3TransferManager transferManager, //
String bucketName, String key, String filePath) {
super();
this.transferManager = transferManager;
this.bucketName = bucketName;
this.key = key;
this.filePath = filePath;
}
private String resumableStateFile(String key) {
return key.replace('/', '_') + "_resumableFileDownload.json";
}
public void pauseDownload() {
if (fileDownload == null || isPause || successfullyCompleted) {
return;
}
System.out.println("--> User calls pauseDownload!");
// Pause the download
ResumableFileDownload resumableFileDownload = fileDownload.pause();
isPause = true;
// Optionally, persist the resumableFileDownload
Path path = Paths.get(this.resumableStateFile(key));
resumableFileDownload.serializeToFile(path);
}
public void resumeDownload() {
if (fileDownload == null || !isPause || successfullyCompleted) {
return;
}
isPause = false;
System.out.println("--> User calls resumeDownload!");
Path path = Paths.get(this.resumableStateFile(key));
// Retrieve the resumableFileDownload from the file
//
// WARNING: Test with: Awssdk 2.21.10
// The "TransferListener" is not restored. (Need to wait for newer version of
// Awssdk)
//
ResumableFileDownload persistedResumableFileDownload = ResumableFileDownload.fromFile(path);
// Resume the download
this.fileDownload = transferManager.resumeDownloadFile(persistedResumableFileDownload);
this.handleCompletionState(fileDownload);
}
@Override
public void run() {
DownloadFileRequest downloadFileRequest = DownloadFileRequest.builder()
.getObjectRequest(req -> req.bucket(bucketName).key(key)) // bucketName & key
.destination(Paths.get(filePath))
// Attaching a LoggingTransferListener that will log the progress
.addTransferListener(LoggingTransferListener.create())//
.build();
// Initiate the transfer
this.fileDownload = transferManager.downloadFile(downloadFileRequest);
this.handleCompletionState(fileDownload);
}
private void handleCompletionState(FileDownload fileDownload) {
try {
CompletedFileDownload completedFileDownload = fileDownload //
.completionFuture() // CompletableFuture<CompletedDirectoryDownload>
.join(); // Wait until completed, and return value.
//
successfullyCompleted = true;
System.out.println("handleCompletionState: SuccessfullyCompleted");
System.out.println(" --> " + completedFileDownload.toString());
} catch (CancellationException e) {
System.out.println("handleCompletionState: CancellationException");
System.out.println(" --> (It could be by the user calling the pause method.)");
} catch (CompletionException e) {
System.out.println("handleCompletionState: Completed with error: " + e);
}
}
}
Viết lớp thi hành interface TransferListener để lắng nghe trạng thái truyền dữ liệu.
MyTransferListener.java
package org.o7planning.java_14249_awssdk_s3;
import software.amazon.awssdk.transfer.s3.progress.TransferListener;
import software.amazon.awssdk.transfer.s3.progress.TransferListener.Context.BytesTransferred;
import software.amazon.awssdk.transfer.s3.progress.TransferListener.Context.TransferComplete;
import software.amazon.awssdk.transfer.s3.progress.TransferListener.Context.TransferFailed;
import software.amazon.awssdk.transfer.s3.progress.TransferListener.Context.TransferInitiated;
import software.amazon.awssdk.transfer.s3.progress.TransferProgressSnapshot;
public class MyTransferListener implements TransferListener {
@Override
public void bytesTransferred(BytesTransferred context) {
TransferProgressSnapshot progress = context.progressSnapshot();
System.out.println("MyTransferListener.bytesTransferred: " //
+ (progress.ratioTransferred().getAsDouble() * 100) + " %");
}
@Override
public void transferInitiated(TransferInitiated context) {
TransferProgressSnapshot progress = context.progressSnapshot();
System.out.println("MyTransferListener.transferInitiated: " //
+ progress.ratioTransferred().getAsDouble());
}
@Override
public void transferComplete(TransferComplete context) {
TransferProgressSnapshot progress = context.progressSnapshot();
System.out.println("MyTransferListener.bytesTransferred: " //
+ progress.ratioTransferred().getAsDouble());
}
@Override
public void transferFailed(TransferFailed context) {
System.out.println("MyTransferListener.transferFailed (Or pause called): " //
+ context.exception().toString());
}
}
Viết một lớp để mô phỏng việc người dùng tạm dừng việc download và tiếp tục lại việc download sau đó.
ResumableFileDownloadThreadTest.java
package org.o7planning.java_14249_awssdk_s3;
import java.time.Duration;
import org.o7planning.java_14249_awssdk_s3.utils.MyUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
public class ResumableFileDownloadThreadTest {
private static final Region MY_BUCKET_REGION = Region.EU_CENTRAL_1;
private static final String BUCKET_NAME = "my-bucket-name";
public static void main(String[] args) {
S3TransferManager transferManager = MyUtils.createS3TransferManager(MY_BUCKET_REGION);
// Test with a large File...
ResumableFileDownloadThread downloadThread = new ResumableFileDownloadThread(transferManager, //
BUCKET_NAME, // bucketName
"static/videos/sample-16m.mp4", // key (171MB)
"/Volumes/New/Test/download/sample-16m.mp4" // filePath
);
//
downloadThread.start();
try {
Thread.sleep(Duration.ofSeconds(60));
} catch (InterruptedException e) {
e.printStackTrace();
}
// The User calls pauseDownload method.
downloadThread.pauseDownload();
try {
Thread.sleep(Duration.ofSeconds(3));
} catch (InterruptedException e) {
e.printStackTrace();
}
// The User calls resumeDownload method.
downloadThread.resumeDownload();
}
}
Output:
[Thread-1] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - Transfer initiated...
[AwsEventLoop 9] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - | | 3.0%
[Thread-2] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - |= | 6.0%
[Thread-2] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - |== | 12.1%
[Thread-3] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - |=== | 15.1%
[Thread-3] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - |==== | 21.2%
[AwsEventLoop 9] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - |===== | 27.3%
[AwsEventLoop 9] INFO software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - |====== | 30.3%
--> User calls pauseDownload!
handleCompletionState: CancellationException
--> (It could be by the user calling the pause method.)
[main] WARN software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener - Transfer failed.
java.util.concurrent.CancellationException
at java.base/java.util.concurrent.CompletableFuture.cancel(CompletableFuture.java:2510)
at software.amazon.awssdk.transfer.s3.internal.model.DefaultFileDownload.doPause(DefaultFileDownload.java:64)
at software.amazon.awssdk.utils.Lazy.getValue(Lazy.java:50)
at software.amazon.awssdk.transfer.s3.internal.model.DefaultFileDownload.pause(DefaultFileDownload.java:60)
at org.o7planning.java_14249_awssdk_s3.ResumableFileDownloadThread.pauseDownload(ResumableFileDownloadThread.java:45)
at org.o7planning.java_14249_awssdk_s3.ResumableFileDownloadThreadTest.main(ResumableFileDownloadThreadTest.java:32)
--> User calls resumeDownload!
handleCompletionState: SuccessfullyCompleted
--> CompletedFileDownload(response=GetObjectResponse(AcceptRanges=bytes, LastModified=2023-11-03T05:03:30Z, ContentLength=120308024, ETag="8b7b7bb1f884ede76fd170c32eb00051-17", ContentRange=bytes 52428800-172736823/172736824, ContentType=application/octet-stream, ServerSideEncryption=AES256, Metadata={}))
Các hướng dẫn Amazon Web Services
- Giới thiệu về Amazon Web Services (AWS)
- Giới thiệu về Amazon S3
- Giới thiệu về Amazon Cloudfront và kiến trúc của nó
- Làm sao để giảm chi phí Amazon Cloudfront?
- Vô hiệu hoá bộ nhớ đệm CloudFront
- Giới thiệu về DigitalOcean Spaces
- Hướng dẫn tạo DigitalOcean Spaces Bucket
- Giới thiệu về Amazon ACM
- Java Awssdk S3 Tải tệp lên S3 Bucket với S3Client
- Tạo AWS accessKeyId/secretAccessKey
- Java Awssdk S3 Liệt kê các đối tượng trong S3 Bucket
- Lưu trữ (host) một Website tĩnh trên Amazon S3
- Vô hiệu hoá bộ nhớ đệm của CloudFront với Java
- Tạo DigitalOcean Spaces Access Key
- Java Awssdk Các Credentials Provider thông dụng
- Java Awssdk Tạo và sử dụng ProfileCredentialsProvider
- Java Awssdk Tạo và sử dụng EnvironmentVariableCredentialsProvider
- Java Awssdk Tạo và sử dụng SystemPropertyCredentialsProvider
- Java Awssdk S3 Tải object lên với S3TransferManager
- Java Awssdk S3 Tải object xuống với S3TransferManager
- Java thao tác với DigitalOcean Spaces sử dụng S3TransferManager
- Java tạo, liệt kê và xoá S3 Bucket
- Aws Console Tạo tài khoản người dùng IAM
- Tạo một vùng chứa Amazon S3 (S3 Bucket)
- Các quy tắc chuyển hướng cho S3 Static Website
- Cấu hình tên miền tuỳ chỉnh cho website tĩnh Amazon S3
- Tạo bản phân phối CloudFront cho S3 Bucket
- Cấu hình các trang phản hồi lỗi cho CloudFront
- Tạo các chính sách S3 Bucket
- Công cụ tạo các chính sách cho AWS - policygen
- So sánh Amazon S3 Rest API Endpoint và S3 Web Endpoint
- Chuyển hướng trong S3 Website với x-amz-website-redirect-location
- Di chuyển (migrate) dịch vụ DNS tới Amazon Route 53
- Chuyển (transfer) đăng ký tên miền tới Amazon Route 53
- Yêu cầu chứng chỉ SSL từ Amazon ACM
Show More