目錄
創(chuàng)建存儲桶
登錄亞馬遜控制臺 查找服務(wù)“S3” 進(jìn)入存儲桶創(chuàng)建頁面;
點擊 “創(chuàng)建存儲桶”進(jìn)入創(chuàng)建頁面;
獲取密鑰ID和密鑰
點擊右上方賬戶信息在下拉菜單中選擇 “安全憑證”(Security credentials)進(jìn)入我的安全憑證頁面;
下滑找到 “訪問密鑰”標(biāo)簽 ?點擊右側(cè)? “創(chuàng)建訪問密鑰”按鈕;
步驟一: “訪問密鑰最佳實踐和替代方案” 選擇適合自己的方案
步驟二:“設(shè)置描述標(biāo)簽”可不填
步驟三 “檢索訪問密鑰“
關(guān)閉屏蔽公共訪問權(quán)限
點擊創(chuàng)建的存儲桶名稱進(jìn)入詳情頁面后點擊“權(quán)限”標(biāo)簽
找到 “屏蔽公共訪問權(quán)限” 點擊下方 “編輯” 按鈕
取消勾選“阻止所有公開訪問”然后點擊下方 “保存更改” 按鈕;在彈出的確認(rèn)框中輸入“確認(rèn)”后點擊“確認(rèn)”按鈕即可生效。
創(chuàng)建存儲桶訪問策略
點擊創(chuàng)建的存儲桶名稱進(jìn)入詳情頁面后點擊“權(quán)限”標(biāo)簽
找到存儲桶策略 -> 點擊右側(cè)“編輯”
創(chuàng)建如下訪問策略
代碼示例
????????首先導(dǎo)入依賴
? ? ? ? 工具類
國內(nèi)使用s3的坑點:?
亞馬遜中國區(qū),必須進(jìn)行ICP 備案,申請開發(fā)80或443端口,否則是不能通過網(wǎng)址直接訪問s3內(nèi)部對象的。
備注:以下操作基于您已有AWS賬戶;
需要獲取:存儲桶名稱、所選區(qū)域、密鑰ID和密鑰;
創(chuàng)建存儲桶
-
登錄亞馬遜控制臺 查找服務(wù)“S3” 進(jìn)入存儲桶創(chuàng)建頁面;
點擊 “創(chuàng)建存儲桶”進(jìn)入創(chuàng)建頁面;
- 輸入存儲桶名稱 、選擇區(qū)域;
????????2. 其他設(shè)置保持默認(rèn)即可;
????????3. 點擊 “創(chuàng)建存儲桶”,即可完成存儲桶的創(chuàng)建;
獲取密鑰ID和密鑰
點擊右上方賬戶信息在下拉菜單中選擇 “安全憑證”(Security credentials)進(jìn)入我的安全憑證頁面;
下滑找到 “訪問密鑰”標(biāo)簽 ?點擊右側(cè)? “創(chuàng)建訪問密鑰”按鈕;
- 進(jìn)入創(chuàng)建訪問密鑰之后
步驟一: “訪問密鑰最佳實踐和替代方案” 選擇適合自己的方案
- ?勾選下方復(fù)選框
- 點擊下一步;
步驟二:“設(shè)置描述標(biāo)簽”可不填
- 點擊 “創(chuàng)建訪問密鑰”按鈕即可創(chuàng)建密鑰;
步驟三 “檢索訪問密鑰“
- 點擊“下載.csv文件“ 保存密鑰ID和密鑰
- 注意:請保存好下載的.csv文件,離開此頁面后“密鑰”將沒有地方獲取查看;
關(guān)閉屏蔽公共訪問權(quán)限
點擊創(chuàng)建的存儲桶名稱進(jìn)入詳情頁面后點擊“權(quán)限”標(biāo)簽
找到 “屏蔽公共訪問權(quán)限” 點擊下方 “編輯” 按鈕
取消勾選“阻止所有公開訪問”然后點擊下方 “保存更改” 按鈕;在彈出的確認(rèn)框中輸入“確認(rèn)”后點擊“確認(rèn)”按鈕即可生效。
創(chuàng)建存儲桶訪問策略
點擊創(chuàng)建的存儲桶名稱進(jìn)入詳情頁面后點擊“權(quán)限”標(biāo)簽
文章來源:http://www.zghlxwxcb.cn/news/detail-830192.html
-
找到存儲桶策略 -> 點擊右側(cè)“編輯”
文章來源地址http://www.zghlxwxcb.cn/news/detail-830192.html
-
創(chuàng)建如下訪問策略
{
"Version": "2012-10-17",
"Id": "GetImgAndPdf",
"Statement": [
{
"Sid": "GetImgAndPdf123",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws-cn:s3:::所創(chuàng)建存儲桶名稱/*"
}
]
}
代碼示例
????????首先導(dǎo)入依賴
<dependencyManagement>
<dependencies>
<!-- aws s3 -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>${awsjavasdk.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- amazon s3 -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>kms</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3control</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3-transfer-manager</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk.crt</groupId>
<artifactId>aws-crt</artifactId>
<version>0.24.0</version>
</dependency>
</dependencies>
? ? ? ? 工具類
package com.trainingos.file.utils;
import com.trainingos.common.util.StringUtils;
import com.trainingos.common.util.file.FileTypeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.http.entity.ContentType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.*;
import software.amazon.awssdk.services.s3.model.*;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
/**
* @Description 亞馬遜文件上傳工具類
* @Author ajie
**/
@Slf4j
public class FileS3Utils {
/**
* 密鑰ID
*/
@Value("${aws.s3.accessKeyId}")
private String accessKeyId;
/**
* 密鑰
*/
@Value("${aws.s3.secretKey}")
private String secretKey;
/*@Value("${aws.s3.s3Uri}")
private String s3Uri;*/
/**
* 存儲桶名字
*/
@Value("${aws.s3.bucket}")
private String bucketName;
/**
* 地區(qū)節(jié)點
*/
@Value("${aws.s3.region}")
private String regionCode;
/**
* 資源映射前綴
*/
@Value("${aws.s3.path}")
private String filePathPrefix;
public static String S3_ACCESS_KEY_ID = null;
public static String S3_SECRET_KEY = null;
//public static String S3_URI = null;
public static String S3_BUCKET = null;
public static String S3_REGION = null;
public static String S3_PATH_PREFIX = null;
/**
* 初始化
*/
@PostConstruct
public void init() {
S3_ACCESS_KEY_ID = accessKeyId;
S3_SECRET_KEY = secretKey;
//S3_URI = s3Uri;
S3_BUCKET = bucketName;
S3_REGION = regionCode;
S3_PATH_PREFIX = filePathPrefix;
}
/**
* S3客戶端對象
*/
private static S3Client s3Client;
public static S3TransferManager transferManager;
/**
* 預(yù)簽名對象
*/
private static S3Presigner s3Presigner;
/**
* 獲取S3客戶端對象
*
* @return S3Client
*/
public static synchronized S3Client getS3Client() {
if (null == s3Client) {
s3Client = S3Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(S3_ACCESS_KEY_ID, S3_SECRET_KEY)))
//.endpointConfiguration(new AwsClientBuilder.EndpointConfiguration(hostName, region)) // 如果有endpoint,可以用這個,這個和withRegion(Region)不能一起使用
//.withPathStyleAccessEnabled(true) // 如果配置了S3域名,就需要加這個進(jìn)行路徑訪問,要不然會報AccessKey不存在的問題
.region(Region.of(S3_REGION))
.build();
}
return s3Client;
}
/**
* 上傳大文件 高級API
* @return
*/
private static synchronized S3TransferManager getTransferManager(){
if(null == transferManager){
S3AsyncClient s3AsyncClient =
S3AsyncClient.crtBuilder()
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(S3_ACCESS_KEY_ID, S3_SECRET_KEY)))
.region(Region.of(S3_REGION))
//.targetThroughputInGbps(20.0)
//.minimumPartSizeInBytes(8 * MB)
.build();
transferManager =
S3TransferManager.builder()
.s3Client(s3AsyncClient)
.build();
}
return transferManager;
}
/**
* 獲取預(yù)簽名對象
*
* @return
*/
public static synchronized S3Presigner getS3PreSigner() {
if (null == s3Presigner) {
s3Presigner = S3Presigner.builder()
// 憑證
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(S3_ACCESS_KEY_ID, S3_SECRET_KEY)))
//.endpointOverride(URI.create(S3_URI))
// 服務(wù)配置
//.serviceConfiguration(S3Configuration.builder().checksumValidationEnabled(false).pathStyleAccessEnabled(true).build())
// 區(qū)域
.region(Region.of(S3_REGION))
.build();
}
return s3Presigner;
}
/**
* 上傳文件
*
* @param s3
* @param bucketName
* @param awsFilePrefix aws資源映射前綴
* @param file
* @param catalog
* @return
* @throws IOException
*/
public static String uploadPublicFile(S3Client s3, String bucketName, String awsFilePrefix, MultipartFile file, String catalog) throws IOException {
// 生成新文件名
String fileName = FileUploadUtils.extractFilename(file);
try {
String keyName = awsFilePrefix + catalog + "/" + fileName;
log.info("keyName===》 {} ", keyName);
String contentType = FileTypeUtils.getFileType(fileName);
log.info("文件類型===》 {} ", contentType);
// 使用PutObjectRequest來設(shè)置附加的值
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.contentType(contentType)
.contentLength(file.getSize())
.acl(ObjectCannedACL.PUBLIC_READ)
.build();
// 上傳文件
s3.putObject(putObjectRequest, RequestBody.fromBytes(file.getBytes()));
log.info("======上傳成功=======》 {} ", catalog + "/" + fileName);
return catalog + "/" + fileName;
} catch (S3Exception | IOException e) {
log.info("上傳文件:", e);
throw new IOException(e.getMessage(), e);
}
}
/**
* 預(yù)覽 有效時間為1天
*
* @param key 文件地址 桶中文件全路徑
* @return
*/
private static String getPreSignatureUrl(S3Presigner s3Presigner, String bucketName, String key) throws Exception {
String preSignatureUrl = "";
try {
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build();
//設(shè)置預(yù)簽名URL可訪問時間 1天
GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder()
.signatureDuration(Duration.ofDays(1))
.getObjectRequest(getObjectRequest)
.build();
PresignedGetObjectRequest presignedGetObjectRequest = s3Presigner.presignGetObject(getObjectPresignRequest);
preSignatureUrl = String.valueOf(presignedGetObjectRequest.url());
} catch (Exception e) {
log.info("生成預(yù)簽名URL失敗,異常: ", e);
throw new Exception(e.getMessage(), e);
}
return preSignatureUrl;
}
/**
* 檢查對象是否存在
*
* @param s3Client s3客戶端
* @param key 文件在桶中的全路徑地址
* @return
*/
public static boolean checkIfObjectExists(S3Client s3Client, String bucketName, String key) {
try {
HeadObjectRequest headObjectRequest = HeadObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build();
s3Client.headObject(headObjectRequest);
return true; // 對象存在
} catch (NoSuchKeyException e) {
return false; // 對象不存在
} catch (S3Exception e) {
log.info("Error checking if object exists: ", e);
return false; // 其他錯誤
}
}
/**
* 流的方式上傳文件到s3桶
*
* @param s3Client
* @param bucketName
* @param key
* @param file
*/
public static void uploadFileStream(S3Client s3Client, String bucketName, String key, File file) {
try {
FileInputStream fileInputStream = new FileInputStream(file);
PutObjectRequest objectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build();
// 使用 RequestBody.fromInputStream 方法將文件流上傳到 S3
s3Client.putObject(objectRequest, RequestBody.fromInputStream(fileInputStream, file.length()));
System.out.println("File uploaded to S3 successfully.");
} catch (Exception e) {
System.err.println("Error uploading file to S3: " + e.getMessage());
}
}
/**
* 獲取桶中某目錄下所有文件
*
* @param s3Client
* @param bucketName
* @param prefix 指定前綴,例如文件夾路徑
* @return
*/
public static List<S3Object> listFilesInBucket(S3Client s3Client, String bucketName, String prefix) {
ListObjectsV2Request listObjectsRequest = ListObjectsV2Request.builder()
.bucket(bucketName)
.prefix(prefix)
.build();
ListObjectsV2Response response = s3Client.listObjectsV2(listObjectsRequest);
return response.contents();
}
/**
* 上傳對象
*/
// public static void main(String[] args){
//
// try{
// Long start = System.currentTimeMillis();
// String baseUrl = "upload/images/common/";
//
// //File file = new File("C://Users//阿杰//Pictures//微信圖片_20220106110701.png");
// File file = new File("C://Users//阿杰//Videos//《歷史關(guān)頭——紅色紀(jì)念館之旅》第二集:星星之火,可以燎原.mp4");
//
// boolean b = checkIfObjectExists(getS3Client(), "《歷史關(guān)頭——紅色紀(jì)念館之旅》第二集:星星之火,可以燎原.mp4");
// if(b){
// log.info("============文件已存在=====");
// return;
// }
// //multipartUpload(baseUrl + "/《歷史關(guān)頭——紅色紀(jì)念館之旅》第二集:星星之火,可以燎原.mp4",file);
//
// //MultipartFile multipartFile = getMultipartFile(file);
//
// //String address = uploadPublicFile(baseUrl, multipartFile);
// log.info("===========上傳完成=====用時:{}",(double)(System.currentTimeMillis()-start)/1000);
// //log.info("=========文件地址=====》 {} ", address);
//
// //String upload = FileUploadUtils.upload("D:/wenjian/project" + File.separator + "png", multipartFile);
// //log.info("=========文件地址=====》 {} ", upload);
//
// log.info("================================================");
//
// //String preview = getPreSignatureUrl(baseUrl + "2023/11/06/《歷史關(guān)頭——紅色紀(jì)念館之旅》第二集:星星之火,可以燎原_20231106150748A001.mp4");
// //log.info("=========文件預(yù)覽地址=====》 {} ", preview);
//
// //getURL(baseUrl + "《歷史關(guān)頭——紅色紀(jì)念館之旅》第二集:星星之火,可以燎原.mp4");
//
// //===================================================
// }catch (Exception e){
// log.info("============",e);
// }
// }
/**
* file 轉(zhuǎn) MultipartFile
*
* @param file
* @return
*/
public static MultipartFile converFileToMultipartFile(File file) throws IOException {
InputStream inputStream = new FileInputStream(file);
return new MockMultipartFile(file.getName(), file.getName(), ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
}
/**
* 轉(zhuǎn)換 MultipartFile 為 File 對象
*
* @param multipartFile
* @return
* @throws IOException
*/
public static File convertMultipartFileToFile(MultipartFile multipartFile) throws IOException {
File file = new File(Objects.requireNonNull(multipartFile.getOriginalFilename()));
try (OutputStream os = new FileOutputStream(file)) {
os.write(multipartFile.getBytes());
}
return file;
}
private static final long PART_SIZE = 100 * 1024 * 1024; // 設(shè)置文件分段大小 100 M
/**
* 計算分段數(shù)量
*/
public static long getPartNumber(long fileLength) {
if (fileLength % PART_SIZE == 0) {
return fileLength / PART_SIZE;
} else {
return fileLength / PART_SIZE + 1;
}
}
private static void multipartUpload(S3Client s3Client, String bucketName, String objectKey, File file) {
CreateMultipartUploadRequest createMultipartUploadRequest = CreateMultipartUploadRequest.builder()
.bucket(bucketName)
.key(objectKey)
.build();
CreateMultipartUploadResponse response = s3Client.createMultipartUpload(createMultipartUploadRequest);
String uploadId = response.uploadId();
try {
FileInputStream fis = new FileInputStream(file);
List<CompletedPart> completedParts = new ArrayList<>();
final long fileLength = file.length();
final long partNumber = getPartNumber(fileLength);
log.info("multipartUpload fileLength={}, partNumber={},uploadId={}", fileLength, partNumber, uploadId);
for (int i = 1; i <= partNumber; i++) {
final byte[] bytes = fis.readNBytes((int) PART_SIZE);
//String md5 = new String(Base64.encodeBase64(DigestUtils.md5(bytes)));
UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
.bucket(bucketName)
.key(objectKey)
.uploadId(uploadId)
.partNumber(i)
//.contentMD5(md5)
.build();
final RequestBody requestBody = RequestBody.fromBytes(bytes);
UploadPartResponse uploadPartResponse = s3Client.uploadPart(uploadPartRequest, requestBody);
String eTag = uploadPartResponse.eTag();
CompletedPart part = CompletedPart.builder().partNumber(i).eTag(eTag).build();
completedParts.add(part);
}
CompletedMultipartUpload completedMultipartUpload = CompletedMultipartUpload.builder()
.parts(completedParts)
.build();
CompleteMultipartUploadRequest completeMultipartUploadRequest =
CompleteMultipartUploadRequest.builder()
.bucket(bucketName)
.key(objectKey)
.uploadId(uploadId)
.multipartUpload(completedMultipartUpload)
.build();
s3Client.completeMultipartUpload(completeMultipartUploadRequest);
} catch (Exception e) {
log.error("S3 multipartUpload fail!", e);
// 停止正在進(jìn)行的分段上傳,清理已上傳分段
s3Client.abortMultipartUpload(AbortMultipartUploadRequest.builder()
.bucket(bucketName)
.key(objectKey)
.uploadId(uploadId)
.build());
}
}
/*public static void main(String[] args) {
Long start = System.currentTimeMillis();
// 設(shè)置所在的AWS Region
Region region = Region.of(S3_REGION); // 根據(jù)您的需求更改Region
// 創(chuàng)建 S3 客戶端
S3Client s3 = S3Client.builder().credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(S3_ACCESS_KEY_ID, S3_SECRET_KEY))).region(region).build();
// 定義所使用的存儲桶和文件鍵值
String bucketName = "nxbvideo"; // 請?zhí)鎿Q為您要使用的存儲桶名稱
String key = "《歷史關(guān)頭——紅色紀(jì)念館之旅》第二集:星星之火,可以燎原.mp4"; // 請?zhí)鎿Q為您要上傳的文件的鍵值
// 定義本地文件路徑
Path filePath = Paths.get("C://Users//阿杰//Videos//《歷史關(guān)頭——紅色紀(jì)念館之旅》第二集:星星之火,可以燎原.mp4"); // 請?zhí)鎿Q為您要上傳的本地文件路徑
// 開始分段上傳
String uploadId = initiateMultipartUpload(s3, bucketName, key);
// 選擇每個分段的大?。?00MB),可以根據(jù)需要調(diào)整分段大小
long partSize = 100 * 1024 * 1024;
// 分割文件并上傳每個部分
List<CompletedPart> completedParts = uploadParts(s3, bucketName, key, filePath, partSize,uploadId);
System.out.println("completedParts 分了==========>"+completedParts.size());
// 完成分段上傳
completeMultipartUpload(s3, bucketName, key, uploadId, completedParts);
log.info("===========上傳完成=====用時:{}",(double)(System.currentTimeMillis()-start)/1000);
// 關(guān)閉 S3 客戶端
s3.close();
}*/
// 初始化分段上傳
public static String initiateMultipartUpload(S3Client s3, String bucketName, String key) {
CreateMultipartUploadResponse response = s3.createMultipartUpload(
CreateMultipartUploadRequest.builder()
.bucket(bucketName)
.key(key)
.build()
);
return response.uploadId();
}
// 分割文件并上傳每個部分
public static List<CompletedPart> uploadParts(S3Client s3, String bucketName, String key, Path filePath, long partSize, String uploadId) {
List<CompletedPart> completedParts = new ArrayList<>();
try {
long filePosition = 0;
long contentLength = filePath.toFile().length();
for (int partNumber = 1; filePosition < contentLength; partNumber++) {
long remainingBytes = contentLength - filePosition;
long byteCount = Math.min(partSize, remainingBytes);
UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
.bucket(bucketName)
.key(key)
.uploadId(uploadId)
.partNumber(partNumber)
.contentLength(byteCount)
.build();
UploadPartResponse response = s3.uploadPart(
uploadPartRequest,
RequestBody.fromFile(filePath)
);
completedParts.add(CompletedPart.builder()
.partNumber(partNumber)
.eTag(response.eTag())
.build());
filePosition += byteCount;
}
return completedParts;
} catch (Exception e) {
System.err.println("Multipart upload failed: " + e.getMessage());
s3.abortMultipartUpload(AbortMultipartUploadRequest.builder()
.bucket(bucketName)
.key(key)
.uploadId(uploadId)
.build());
return null;
}
}
// 中止分段上傳
public static void abortMultipartUpload(S3Client s3, String bucketName, String key, String uploadId) {
s3.abortMultipartUpload(AbortMultipartUploadRequest.builder()
.bucket(bucketName)
.key(key)
.uploadId(uploadId)
.build());
System.out.println("Multipart upload aborted.");
}
// 續(xù)傳分段
public static void resumeMultipartUpload(S3Client s3, String bucketName, String key, Path filePath, long partSize, String uploadId, List<CompletedPart> completedParts) {
// 重新初始化分段上傳
uploadId = initiateMultipartUpload(s3, bucketName, key);
// 檢查哪些分段已經(jīng)上傳
long partNumber = completedParts.size() + 1;
long filePosition = completedParts.stream()
.mapToLong(part -> part.partNumber())
.sum() * partSize;
try {
long contentLength = filePath.toFile().length();
for (; filePosition < contentLength; partNumber++) {
long remainingBytes = contentLength - filePosition;
long byteCount = Math.min(partSize, remainingBytes);
UploadPartResponse response = s3.uploadPart(
UploadPartRequest.builder()
.bucket(bucketName)
.key(key)
.uploadId(uploadId)
.partNumber((int) partNumber)
.contentLength(byteCount)
.build(),
RequestBody.fromFile(filePath)
);
completedParts.add(CompletedPart.builder()
.partNumber((int) partNumber)
.eTag(response.eTag())
.build());
filePosition += byteCount;
}
// 完成續(xù)傳的分段上傳
completeMultipartUpload(s3, bucketName, key, uploadId, completedParts);
} catch (Exception e) {
System.err.println("Multipart upload failed: " + e.getMessage());
abortMultipartUpload(s3, bucketName, key, uploadId);
}
}
// 完成分段上傳
public static void completeMultipartUpload(S3Client s3, String bucketName, String key, String uploadId, List<CompletedPart> completedParts) {
CompleteMultipartUploadResponse response = s3.completeMultipartUpload(
CompleteMultipartUploadRequest.builder()
.bucket(bucketName)
.key(key)
.uploadId(uploadId)
.multipartUpload(CompletedMultipartUpload.builder().parts(completedParts).build())
.build()
);
System.out.println("Multipart upload completed. ETag: " + response.eTag());
// 因為在分段上傳過程中,單獨的每個分段并不包含文件的完整 Metadata。
// 在完成上傳之后,使用 CopyObjectRequest 設(shè)置文件類型
// 創(chuàng)建 Metadata 對象并設(shè)置文件類型
/*Map<String, String> metadata = new HashMap<>();
metadata.put("Content-Type", "application/zip");
CopyObjectRequest copyObjectRequest = CopyObjectRequest.builder()
.copySource(bucketName + "/" + key)
.destinationBucket(bucketName)
.destinationKey(key)
.metadataDirective(MetadataDirective.REPLACE) // 覆蓋現(xiàn)有元數(shù)據(jù)
.metadata(metadata)
.build();
s3.copyObject(copyObjectRequest);
System.out.println("Multipart upload completed. Content-Type set to application/zip.");*/
}
// 分片上傳
/*public static void main(String[] args) {
String bucketName = S3_BUCKET;
String key = "upload/images/common/《歷史關(guān)頭——紅色紀(jì)念館之旅》第二集:星星之火,可以燎原.mp4"; // 文件在 S3 中的鍵
String filePathString = "C://Users//阿杰//Videos//《歷史關(guān)頭——紅色紀(jì)念館之旅》第二集:星星之火,可以燎原.mp4"; // 本地文件路徑
// 創(chuàng)建 S3 客戶端
S3Client s3 = S3Client.builder()
.region(Region.of(S3_REGION)) // 設(shè)置您的 S3 存儲桶所在的區(qū)域
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(S3_ACCESS_KEY_ID, S3_SECRET_KEY)))
.build();
// 指定要上傳的本地文件路徑
Path filePath = Path.of(filePathString);
// 設(shè)置分段大小
final long PART_SIZE = 50 * 1024 * 1024; // 每個分段的大小為 50MB
// 創(chuàng)建 InitiateMultipartUploadRequest 請求
CreateMultipartUploadRequest createRequest = CreateMultipartUploadRequest.builder()
.bucket(bucketName)
.key(key)
.build();
// 初始化分段上傳
CreateMultipartUploadResponse createResponse = s3.createMultipartUpload(createRequest);
// 獲取文件大小
long contentLength = filePath.toFile().length();
// 計算分段數(shù)量
long partCount = (contentLength + PART_SIZE - 1) / PART_SIZE;
// 創(chuàng)建一個線程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
try {
List<Future<CompletedPart>> futures = new ArrayList<>();
// 逐個上傳文件的分段
for (int i = 1; i <= partCount; i++) {
long filePosition = (i - 1) * PART_SIZE;
long partSize = Math.min(PART_SIZE, contentLength - filePosition);
// 開啟線程上傳分段
int finalI = i;
Future<CompletedPart> future = executorService.submit(() -> {
UploadPartRequest uploadRequest = UploadPartRequest.builder()
.bucket(bucketName)
.key(key)
.uploadId(createResponse.uploadId())
.partNumber(finalI)
.build();
// 讀取文件分段內(nèi)容
RequestBody requestBody = RequestBody.fromFile(filePath);
// 上傳分段
UploadPartResponse uploadPartResponse = s3.uploadPart(uploadRequest, requestBody);
return CompletedPart.builder()
.partNumber(finalI)
.eTag(uploadPartResponse.eTag())
.build();
});
futures.add(future);
}
List<CompletedPart> completedParts = new ArrayList<>();
for (Future<CompletedPart> future : futures) {
completedParts.add(future.get());
}
// 完成分段上傳
CompleteMultipartUploadRequest completeRequest = CompleteMultipartUploadRequest.builder()
.bucket(bucketName)
.key(key)
.uploadId(createResponse.uploadId())
.multipartUpload(CompletedMultipartUpload.builder()
.parts(completedParts)
.build())
.build();
s3.completeMultipartUpload(completeRequest);
System.out.println("Multipart upload completed.");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 關(guān)閉 S3 客戶端和線程池
s3.close();
executorService.shutdown();
}
}*/
// 上傳大文件
/*public static String uploadFile(S3TransferManager transferManager, String bucketName,
String baseDir, MultipartFile file, String catalog){
// 生成新文件名
String fileName = FileUploadUtils.extractFilename(file);
String keyName = baseDir + catalog + "/" + fileName;
log.info("生成的文件路徑===》 {} ", keyName);
try{
UploadFileRequest uploadFileRequest =
UploadFileRequest.builder()
.putObjectRequest(b -> b.bucket(bucketName).key(keyName))
.addTransferListener(LoggingTransferListener.create())
//.source(file.)
.build();
FileUpload fileUpload = transferManager.uploadFile(uploadFileRequest);
CompletedFileUpload uploadResult = fileUpload.completionFuture().join();
String s = uploadResult.response().eTag();
return s;
}catch (Exception e){
log.info("======",e);
}
return "";
}*/
/**
* 上傳大文件
* @param transferManager
* @param bucketName
* @param key
* @param filePath
* @return
*/
/*public String uploadFile(S3TransferManager transferManager, String bucketName,
String key, String filePath) {
UploadFileRequest uploadFileRequest =
UploadFileRequest.builder()
.putObjectRequest(b -> b.bucket(bucketName).key(key))
.addTransferListener(LoggingTransferListener.create())
.source(Paths.get(filePath))
.build();
FileUpload fileUpload = transferManager.uploadFile(uploadFileRequest);
CompletedFileUpload uploadResult = fileUpload.completionFuture().join();
return uploadResult.response().eTag();
}*/
}
國內(nèi)使用s3的坑點:?
亞馬遜中國區(qū),必須進(jìn)行ICP 備案,申請開發(fā)80或443端口,否則是不能通過網(wǎng)址直接訪問s3內(nèi)部對象的。
到了這里,關(guān)于Amazon s3 sdk for java2.x 最新api的簡單使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!