AWS S3常用功能总结回顾

本文用于记录与分享工作中遇到的s3的基础使用方法

工具介绍

本文采用s3Browser对s3进行可视化管理
在这里插入图片描述

基本元素

  1. 端点Endpoint
  2. 桶Bucket
  3. 账号AccessKey
  4. 密码SecreteKey

说明

本文基于JavaSDK进行演示代码,下文的代码都只包含核心部分,异常捕捉、流关闭、S3客户端、端点信息等细节可能会被省略

Maven依赖

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk</artifactId>
    <version>1.11.891</version>
</dependency>

s3Browser下载地址

https://s3browser.com/download.aspx

存储桶管理

S3上的数据都是存储在桶内的,可以理解为自己账号下的文件夹。桶之间是隔离的。

命名规范

推荐桶名称如下:

docexamplebucket1
log-delivery-march-2020
my-hosted-content

无效桶名称:

doc_example_bucket(包含下划线)
DocExampleBucket(包含大写字母)
doc-example-bucket-(以连字符结尾)

桶的访问方式(端点访问)

这里简单介绍一下几种常用的端点命名访问方式

虚拟主机(推荐使用)

url = https://桶名.[区域码].端点地址/文件key

可选参数:区域码

路径类型

url = https://[区域码].端点地址/桶名/文件key

自定义域名

  1. 将自己的域名,cname到厂商的S3 Endpoint上
  2. 在配置页面,将域名映射到某个桶
url = https://自定义域名/桶名/文件key

创建桶

// 声明区域
Regions clientRegion = Regions.DEFAULT_REGION;
String bucketName = "桶名在这里定义";
// s3客户端
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withCredentials(new ProfileCredentialsProvider())
                    .withRegion(clientRegion)
                    .build();
if (!s3Client.doesBucketExistV2(bucketName)) {
	s3Client.createBucket(new CreateBucketRequest(bucketName));
// 验证桶创建成功
String bucketLocation = s3Client.getBucketLocation(new   GetBucketLocationRequest(bucketName));
System.out.println("Bucket location: " + bucketLocation);

删除桶

		// 删除所有对象
         ObjectListing objectListing = s3Client.listObjects(bucketName);
         while (true) {
             Iterator<S3ObjectSummary> objIter = objectListing.getObjectSummaries().iterator();
             while (objIter.hasNext()) {
                 s3Client.deleteObject(bucketName, objIter.next().getKey());
             }
             if (objectListing.isTruncated()) {
                 objectListing = s3Client.listNextBatchOfObjects(objectListing);
             } else {
                 break;
             }
         }
        
        // 删除所有带版本的对象
         VersionListing versionList = s3Client.listVersions(new ListVersionsRequest().withBucketName(bucketName));
         while (true) {
             Iterator<S3VersionSummary> versionIter = versionList.getVersionSummaries().iterator();
             while (versionIter.hasNext()) {
                 S3VersionSummary vs = versionIter.next();
                 s3Client.deleteVersion(bucketName, vs.getKey(), vs.getVersionId());
             }
             if (versionList.isTruncated()) {
                 versionList = s3Client.listNextBatchOfVersions(versionList);
             } else {
                 break;
             }
         }
		// 删除桶
         s3Client.deleteBucket(bucketName);
}

对象管理

上传对象

  AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(clientRegion)
                    .build();
                    
       // 上传一个对象 这里传入一个String
       s3Client.putObject(bucketName, stringObjKeyName, "Uploaded String Object");

       // 指定ContentType 从文件上传对象
       PutObjectRequest request = new PutObjectRequest(bucketName, fileObjKeyName, new File(fileName));
      	//  对象元数据设置
       ObjectMetadata metadata = new ObjectMetadata();
       metadata.setContentType("plain/text");
       metadata.addUserMetadata("title", "someTitle");
       request.setMetadata(metadata);
       s3Client.putObject(request);

下载对象

S3Object fullObject = null, objectPortion = null, headerOverrideObject = null;

AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(clientRegion)
                    .withCredentials(new ProfileCredentialsProvider())
                    .build();

       // 获取对象
       fullObject = s3Client.getObject(new GetObjectRequest(bucketName, key));

       // 获取对象指定字节范围
       GetObjectRequest rangeObjectRequest = new GetObjectRequest(bucketName, key)
               .withRange(0, 9);
       objectPortion = s3Client.getObject(rangeObjectRequest);

      // 指定ResponseHeader
      ResponseHeaderOverrides headerOverrides =
      new ResponseHeaderOverrides()
              .withCacheControl("No-cache")
              .withContentDisposition("attachment; filename=example.txt");
      GetObjectRequest getObjectRequestHeaderOverride = 
      new GetObjectRequest(bucketName, key)
              .withResponseHeaders(headerOverrides);
       headerOverrideObject = s3Client.getObject(getObjectRequestHeaderOverride);

复制对象

// 从bucketName/sourceKey复制到bucketName2/destinationKey
CopyObjectRequest copyObjRequest = new CopyObjectRequest(bucketName, sourceKey, bucketName2, destinationKey);

s3Client.copyObject(copyObjRequest);

删除对象

// 删除单个对象
 s3Client.deleteObject(new DeleteObjectRequest(bucketName, keyName));
// 删除多个对象

// 文件名
ArrayList<KeyVersion> keys = new ArrayList<KeyVersion>();
for (int i = 0; i < 3; i++) {
    String keyName = "keyname " + i;
    keys.add(new KeyVersion(keyName));
}
// 删除多个对象
DeleteObjectsRequest multiObjectDeleteRequest = new DeleteObjectsRequest(bucketName)
        .withKeys(keys)
        .withQuiet(false);

// 验证删除成功
 DeleteObjectsResult delObjRes = s3Client.deleteObjects(multiObjectDeleteRequest);
 int successfulDeletes = delObjRes.getDeletedObjects().size();

列出对象

可以列出桶里所有文件的路径

        ListObjectsRequest listObjects = new ListObjectsRequest().withBucketName("ait-doc");
		
		// 查看所有对象
        ObjectListing res = amazonS3.listObjects(listObjects);
        List<S3ObjectSummary> objectSummaries = res.getObjectSummaries();
        for (S3ObjectSummary myValue : objectSummaries) {
            System.out.print("\n 文件路径:" + myValue.getKey());
        }

分段上传

这里通常有两种API提供给我们使用,第一种是高级API,使用的是TransferManager实现调用,第二种是更底层的低级API,通常我用低级API,更方便定制化开发。

配置生命周期策略

此项用于指定分段上传任务在指定天数内完成上传,否则将会被清除相关联的分段

<LifecycleConfiguration>
    <Rule>
        <ID>sample-rule</ID>
        <Prefix></Prefix>
        <Status>Enabled</Status>
        <AbortIncompleteMultipartUpload>
          <DaysAfterInitiation>7</DaysAfterInitiation>
        </AbortIncompleteMultipartUpload>
    </Rule>
</LifecycleConfiguration>

查看正在进行的分段上传的列表

ListMultipartUploadsRequest allMultpartUploadsRequest = 
     new ListMultipartUploadsRequest(existingBucketName);
MultipartUploadListing multipartUploadListing = 
     s3Client.listMultipartUploads(allMultpartUploadsRequest);

分段上传

分段上传通常用于大文件,前后端配合实现快速上传。
通常分段上传分为三个步骤:

  1. 开启分段上传任务
  2. 上传分段数据
  3. 结束或中断分段上传任务
    任务结束后,会汇聚所有的分段,合并为一个完整的文件,所有的操作都是由S3实现的。
// 分段标签元数据 	
List<PartETag> partETags = new ArrayList<PartETag>();

 // 发起开始分段上传请求
InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(bucketName, keyName);
 InitiateMultipartUploadResult initResponse = s3Client.initiateMultipartUpload(initRequest);

 // 上传分段
 long filePosition = 0;
 for (int i = 1; filePosition < contentLength; i++) {
  	// 最后一个分段可能小于5MB,
 	 partSize = Math.min(partSize, (contentLength - filePosition));

	// 分段上传请求
	UploadPartRequest uploadRequest = new UploadPartRequest()
	        .withBucketName(bucketName)
	        .withKey(keyName)
	        .withUploadId(initResponse.getUploadId())
	        .withPartNumber(i)
	        .withFileOffset(filePosition)
	        .withFile(file)
	        .withPartSize(partSize);

     // 分段上传响应
     UploadPartResult uploadResult = s3Client.uploadPart(uploadRequest);
     partETags.add(uploadResult.getPartETag());

     filePosition += partSize;
 }

 // 关闭分段上传任务
 CompleteMultipartUploadRequest compRequest = new CompleteMultipartUploadRequest(bucketName, keyName,
         initResponse.getUploadId(), partETags);
 s3Client.completeMultipartUpload(compRequest);

中断分段上传

如果不需要结束任务,那么可以中断上传,然后会清理掉所有的分段。

// 低级API
s3Client.abortMultipartUpload(new AbortMultipartUploadRequest(
            existingBucketName, keyName, initResponse.getUploadId()));
// 高级API
TransferManager tm = new TransferManager(new ProfileCredentialsProvider());
// 指定清理一周前启动的 并且还在进行上传的分段
int sevenDays = 1000 * 60 * 60 * 24 * 7;
Date oneWeekAgo = new Date(System.currentTimeMillis() - sevenDays);
tm.abortMultipartUploads(existingBucketName, oneWeekAgo);

跟踪正在上传的分段

TransferManager tm = new TransferManager(new ProfileCredentialsProvider());        

PutObjectRequest request = new PutObjectRequest(
existingBucketName, keyName, new File(filePath));

// 设置监听事件
request.setGeneralProgressListener(new ProgressListener() {
	@Override
	public void progressChanged(ProgressEvent progressEvent) {
		System.out.println("Transferred bytes: " + 
		progressEvent.getBytesTransferred());
	}
});
// 执行上传
Upload upload = tm.upload(request);
// 等待上传完毕
upload.waitForCompletion();

低级API(TransferManager)

TransferManager tm = TransferManagerBuilder.standard()
     .withS3Client(s3Client)
     .build();
// 指定文件路径上传
 Upload upload = tm.upload(bucketName, keyName, new File(filePath));
 // 异步 等待任务完成
 upload.waitForCompletion();

预签名URL

签名URL上传

// 生成请求
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest("ait-doc", "1.png")
	// 查询请求用GET 上传请求用PUT
    .withMethod(HttpMethod.GET)
    .withExpiration(new Date());
// 创建签名URL
URL url = amazonS3.generatePresignedUrl(request);

安全管理

CORS

可以进行跨域配置

<CORSConfiguration>
 <CORSRule>
   <AllowedOrigin>*</AllowedOrigin>
   <AllowedMethod>PUT</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>
   <AllowedHeader>*</AllowedHeader>
  <MaxAgeSeconds>3000</MaxAgeSeconds>
  <ExposeHeader>x-amz-server-side-encryption</ExposeHeader>
  <ExposeHeader>x-amz-request-id</ExposeHeader>
  <ExposeHeader>x-amz-id-2</ExposeHeader>
 </CORSRule>
</CORSConfiguration>

ACL管理访问

管理桶和对象的访问权限,附加在桶和对象上,进行权限控制。S3提供了一系列预定义的ACL叫标准ACL,下表是常用3个的标准ACL。可以使用 x-amz-acl 请求头在请求中指定标准的 ACL。

ACL适用权限描述
private桶和对象所有者将获得 FULL_CONTROL。其他人没有访问权限 (默认)
public-read桶和对象
public-read-write桶和对象所有者将获得 FULL_CONTROL。AllUsers 组将获得 READ 访问权限

参考:
[1] AWS GIthub仓库
[2] AWS官方文档

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值