Amazon s3 sdk for java2.x 最新api的简单使用

目录

创建存储桶

登录亚马逊控制台 查找服务“S3” 进入存储桶创建页面;

点击 “创建存储桶”进入创建页面;

获取密钥ID和密钥

点击右上方账户信息在下拉菜单中选择 “安全凭证”(Security credentials)进入我的安全凭证页面;

下滑找到 “访问密钥”标签  点击右侧  “创建访问密钥”按钮;

步骤一: “访问密钥最佳实践和替代方案” 选择适合自己的方案

步骤二:“设置描述标签”可不填

步骤三 “检索访问密钥“

关闭屏蔽公共访问权限

点击创建的存储桶名称进入详情页面后点击“权限”标签

找到 “屏蔽公共访问权限” 点击下方 “编辑” 按钮

取消勾选“阻止所有公开访问”然后点击下方 “保存更改” 按钮;在弹出的确认框中输入“确认”后点击“确认”按钮即可生效。

创建存储桶访问策略

点击创建的存储桶名称进入详情页面后点击“权限”标签

找到存储桶策略 -> 点击右侧“编辑”

创建如下访问策略

代码示例

        首先导入依赖

        工具类

国内使用s3的坑点: 

亚马逊中国区,必须进行ICP 备案,申请开发80或443端口,否则是不能通过网址直接访问s3内部对象的。


备注:以下操作基于您已有AWS账户;

需要获取:存储桶名称、所选区域、密钥ID和密钥;

创建存储桶

点击 “创建存储桶”进入创建页面;

  1. 输入存储桶名称 、选择区域;

        2. 其他设置保持默认即可;

        3. 点击 “创建存储桶”,即可完成存储桶的创建;

获取密钥ID和密钥

点击右上方账户信息在下拉菜单中选择 “安全凭证”(Security credentials)进入我的安全凭证页面;

下滑找到 “访问密钥”标签  点击右侧  “创建访问密钥”按钮;

  1. 进入创建访问密钥之后

步骤一: “访问密钥最佳实践和替代方案” 选择适合自己的方案

  •  勾选下方复选框
  • 点击下一步;

步骤二:“设置描述标签”可不填

  • 点击 “创建访问密钥”按钮即可创建密钥;

步骤三 “检索访问密钥“

  1. 点击“下载.csv文件“ 保存密钥ID和密钥
  2. 注意:请保存好下载的.csv文件,离开此页面后“密钥”将没有地方获取查看;

关闭屏蔽公共访问权限

点击创建的存储桶名称进入详情页面后点击“权限”标签

找到 “屏蔽公共访问权限” 点击下方 “编辑” 按钮

取消勾选“阻止所有公开访问”然后点击下方 “保存更改” 按钮;在弹出的确认框中输入“确认”后点击“确认”按钮即可生效。

创建存储桶访问策略

点击创建的存储桶名称进入详情页面后点击“权限”标签

  1. 找到存储桶策略 -> 点击右侧“编辑”

  1. 创建如下访问策略

{
    "Version": "2012-10-17",
    "Id": "GetImgAndPdf",
    "Statement": [
        {
            "Sid": "GetImgAndPdf123",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws-cn:s3:::所创建存储桶名称/*"
        }
    ]
}

代码示例

        首先导入依赖

    <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;
    /**
     * 地区节点
     */
    @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;

    /**
     * 预签名对象
     */
    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域名,就需要加这个进行路径访问,要不然会报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;
    }

    /**
     * 获取预签名对象
     *
     * @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))
                    // 服务配置
                    //.serviceConfiguration(S3Configuration.builder().checksumValidationEnabled(false).pathStyleAccessEnabled(true).build())
                    // 区域
                    .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来设置附加的值
            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);
        }
    }

   

    /**
     * 预览 有效时间为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();

            //设置预签名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("生成预签名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//《历史关头——红色纪念馆之旅》第二集:星星之火,可以燎原.mp4");
//
//            boolean b = checkIfObjectExists(getS3Client(), "《历史关头——红色纪念馆之旅》第二集:星星之火,可以燎原.mp4");
//            if(b){
//                log.info("============文件已存在=====");
//                return;
//            }
//            //multipartUpload(baseUrl + "/《历史关头——红色纪念馆之旅》第二集:星星之火,可以燎原.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/《历史关头——红色纪念馆之旅》第二集:星星之火,可以燎原_20231106150748A001.mp4");
//            //log.info("=========文件预览地址=====》 {} ", preview);
//
//            //getURL(baseUrl + "《历史关头——红色纪念馆之旅》第二集:星星之火,可以燎原.mp4");
//
//            //===================================================
//        }catch (Exception e){
//            log.info("============",e);
//        }
//    }


    /**
     * file 转 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);
    }




    /**
     * 转换 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; // 设置文件分段大小 100 M

    /**
     * 计算分段数量
     */
    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);
            // 停止正在进行的分段上传,清理已上传分段
            s3Client.abortMultipartUpload(AbortMultipartUploadRequest.builder()
                    .bucket(bucketName)
                    .key(objectKey)
                    .uploadId(uploadId)
                    .build());
        }

    }


    /*public static void main(String[] args) {
        Long start = System.currentTimeMillis();
        // 设置所在的AWS Region
        Region region = Region.of(S3_REGION); // 根据您的需求更改Region

        // 创建 S3 客户端
        S3Client s3 = S3Client.builder().credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(S3_ACCESS_KEY_ID, S3_SECRET_KEY))).region(region).build();

        // 定义所使用的存储桶和文件键值
        String bucketName = "nxbvideo"; // 请替换为您要使用的存储桶名称
        String key = "《历史关头——红色纪念馆之旅》第二集:星星之火,可以燎原.mp4"; // 请替换为您要上传的文件的键值

        // 定义本地文件路径
        Path filePath = Paths.get("C://Users//阿杰//Videos//《历史关头——红色纪念馆之旅》第二集:星星之火,可以燎原.mp4"); // 请替换为您要上传的本地文件路径

        // 开始分段上传
        String uploadId = initiateMultipartUpload(s3, bucketName, key);

        // 选择每个分段的大小(100MB),可以根据需要调整分段大小
        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);
        // 关闭 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.");
    }

    // 续传分段
    public static void resumeMultipartUpload(S3Client s3, String bucketName, String key, Path filePath, long partSize, String uploadId, List<CompletedPart> completedParts) {
        // 重新初始化分段上传
        uploadId = initiateMultipartUpload(s3, bucketName, key);

        // 检查哪些分段已经上传
        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;
            }

            // 完成续传的分段上传
            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 设置文件类型
        // 创建 Metadata 对象并设置文件类型
        /*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) // 覆盖现有元数据
                .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/《历史关头——红色纪念馆之旅》第二集:星星之火,可以燎原.mp4"; // 文件在 S3 中的键
        String filePathString = "C://Users//阿杰//Videos//《历史关头——红色纪念馆之旅》第二集:星星之火,可以燎原.mp4"; // 本地文件路径

        // 创建 S3 客户端
        S3Client s3 = S3Client.builder()
                .region(Region.of(S3_REGION)) // 设置您的 S3 存储桶所在的区域
                .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(S3_ACCESS_KEY_ID, S3_SECRET_KEY)))
                .build();

        // 指定要上传的本地文件路径
        Path filePath = Path.of(filePathString);

        // 设置分段大小
        final long PART_SIZE = 50 * 1024 * 1024; // 每个分段的大小为 50MB


        // 创建 InitiateMultipartUploadRequest 请求
        CreateMultipartUploadRequest createRequest = CreateMultipartUploadRequest.builder()
                .bucket(bucketName)
                .key(key)
                .build();

        // 初始化分段上传
        CreateMultipartUploadResponse createResponse = s3.createMultipartUpload(createRequest);

        // 获取文件大小
        long contentLength = filePath.toFile().length();

        // 计算分段数量
        long partCount = (contentLength + PART_SIZE - 1) / PART_SIZE;

        // 创建一个线程池
        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();

                    // 读取文件分段内容
                    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 {
            // 关闭 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();
    }*/

}

国内使用s3的坑点: 

亚马逊中国区,必须进行ICP 备案,申请开发80或443端口,否则是不能通过网址直接访问s3内部对象的。
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: software.amazon.awssdk s3 api文档是Amazon Web Services的S3服务的官方API文档。该文档提供了详细的S3 API操作指南和使用示例,包括对象存储、桶(Bucket)管理、访问控制、CORS配置等方面的内容。 该文档主要面向S3服务的开发者,通过对API操作指南的阅读,开发者可以熟悉S3服务的基本操作和使用方式,从而能够更加高效地开发S3相关应用。 除了操作指南之外,该文档还提供了代码示例和API参考,方便开发者编写和调试S3应用程序。所有API都有详细的参数说明和使用示例,以及方法的返回值。 总之,software.amazon.awssdk s3 api文档是S3开发者必备的宝典之一,对于想要了解和掌握S3服务的开发者来说,这本文档会极大地提高他们的开发效率和成果。 ### 回答2: software.amazon.awssdk s3 api文档是AWS S3 SDK的官方文档,其中包括了S3 SDK中所有的API方法和参数说明,以及示例代码。AWS S3 SDKAmazon Web Services(AWS)提供的用于连接和操作AWS S3存储桶的软件开发工具包(SDK)。通过这个SDK,开发人员可以快速地将S3存储桶集成到他们的应用程序中,也可以在应用程序中增加对S3存储桶的功能。文档中描述了各种操作S3存储桶的API方法,如创建、读取、更新和删除存储桶、管理S3存储桶中的对象、设置存储桶权限等等。此外,文档还提供了详细的参数说明,让用户可以了解每个API方法的输入参数、返回参数、请求响应、异常处理等内容。对于想要使用AWS S3 SDK进行开发的用户,软件.amazon.awssdk s3 api文档是必备的参考资料,它能够帮助开发人员更好地了解S3 SDK使用,提高开发效率和开发成功率。 ### 回答3: Software.amazon.awssdk s3 api文档是亚马逊AWS Java 开发工具包中用于与亚马逊S3存储服务交互的应用程序接口(API)文档。该文档提供了详细的开发指南和API文档,帮助开发人员在Java语言下使用AWS S3服务。 该文档的开发指南分为三个部分,即入门、开发和高级。入门部分涵盖了如何设置开发环境、创建AWS S3存储桶以及基本的对象和桶操作。开发部分着重介绍了如何上传和下载大文件、实现上传和下载进度监控和使用加密功能。高级部分则进一步讲解了如何使用对象标记、复制对象和批量操作等高级应用。 在API文档部分,开发人员可以快速了解每个API的用途、入参和出参的具体信息,并可查看示例代码和错误代码,以便更好地理解和运用API。此外,文档还提供了完整的SDK参考文档和一些常见问题的解决方案。 总的来说,软件.amazon.awssdk s3 api文档提供了非常详细的开发指南和API文档,加上丰富的示例代码和SDK文档,极大地方便了开发人员在Java语言下使用AWS S3服务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值