AWS S3存储服务SDK

第三方 专栏收录该内容
4 篇文章 0 订阅

0x0 前言

Amazon Simple Storage Service 是互联网存储解决方案。该服务旨在降低开发人员进行网络规模级计算的难度。

Amazon S3 提供了一个简单 Web 服务接口,可用于随时在 Web 上的任何位置存储和检索任何数量的数据。此服务让所有开发人员都能访问同一个具备高扩展性、可靠性、安全性和快速价廉的数据存储基础设施, Amazon 用它来运行其全球的网站网络。此服务旨在为开发人员带来最大化的规模效益。

0x1 名词介绍

0x1_1 存储桶(Bucket)

存储桶是 Amazon S3 中用于存储对象的容器。每个对象都储存在一个存储桶中。

0x1_2 对象(Object)

对象是 Amazon S3 中存储的基本实体。对象由对象数据和元数据组成。在存储桶中,对象将由键 (名称) 和版本 ID 进行唯一地标识。注:版本ID 非必须,需要再存储桶中配置启用版本控制

0x1_3 键(Key)

键是指存储桶中对象的唯一标识符。存储桶内的每个对象都只能有一个键。由于将存储桶、键和版本 ID 组合在一起可唯一地标识每个对象,可将 Amazon S3 视为一种“存储桶 + 键 + 版本”与对象本身间的基本数据映射。

0x1_4 版本ID(VersionId)

通过VersionId,可以在一个存储桶中保留多个对象版本,例如, report_201706.csv (版本 111111) 和 report_201706.csv (版本 222222)。可以启用版本控制来防止自己意外覆盖和删除版本,或存档对象,以便您可以检索早期版本的对象。如果不启用则相同Key 采用覆盖策略。

  • PUT(开启版本控制):

PUT Version Enalbled

  • DELETE(开启版本控制)

PUT Version Enalbled

0x1_5 区域(Region)

存储桶所在地理区域,在某一区域存储的对象将一直留在该区域,除非您特意将其传输到另一区域。定位对象需要 区域>账户授权(获取账户)>桶>key(+version id)来定位到存储对象。

0x2 起步

0x2_1 操作

对存储桶、对象等操作可以有一下几种方式,本文主要讲解SDK操作:

  • AWS S3控制台操作
  • 命令行操作
  • SDK 操作(多种语言SDK,这里以JAVA SDK为例)
  • REST API

0x2_2 依赖(Maven)

  • 引入AWS SDK 依赖管理
<dependencyManagement>
    <dependencies>
        <!--AWS S3需要至少4.5.2以上版本-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-bom</artifactId>
            <version>1.11.170</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
  • 引入S3-SDK
<dependencies>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-s3</artifactId>
    </dependency>
</dependencies>

0x3 对象操作

所有操作都基于com.amazonaws.services.s3.AmazonS3操作,com.amazonaws.services.s3.AmazonS3ClientAmazonS3的实现。

鉴权对象SDK提供了多种实现:

  • ProfileCredentialsProvider 默认加载~/.aws/credentials 中accessKey 和secretKey
  • PropertiesCredentials 根据配置文件获取accessKey 和secretKey (支持文件和InputStream)
  • BasicAWSCredentials 直接传入accessKey 和secretKey

0x3_1 开启桶版本控制

存储桶版本控制状态分为三种:OFF,ENABLED,SUSPENDED。默认是OFF状态,开启(ENABLED)后,就不能再变更状态为OFF,只能变更为SUSPENDED 暂停版本控制,代码如下:

public class Sample{
    private static String BUCKET_NAME     = "bucket-name";
    private static String ACCESS_KEY = "access_key_id";
    private static String SECRET_KEY = "secret_access_key";
    public static void main(String[] args){
        //初始化AmazonS3
        AmazonS3 s3client = new AmazonS3Client(new BasicAWSCredentials(ACCESS_KEY,SECRET_KEY));
        Region usWest2 = Region.getRegion(Regions.CN_NORTH_1);
        s3client.setRegion(usWest2);
        //开启版本控制
        BucketVersioningConfiguration config = new BucketVersioningConfiguration()
                            .withStatus(BucketVersioningConfiguration.ENABLED);
        SetBucketVersioningConfigurationRequest setBucketVersioningConfigurationRequest = 
                                new SetBucketVersioningConfigurationRequest(BUCKET_NAME, config);
        s3client.setBucketVersioningConfiguration(setBucketVersioningConfigurationRequest);
    }
}

0x3_2 上传对象

S3支持单次操作上传和多次操作分段上传(断点上传),这里只介绍单操作上传,分段上传详见:分段上传

单操作上传:

  1. 创建 AmazonS3Client 的实例。
  2. 根据上传文件或流数据,执行任意一个 AmazonS3Client.putObject 重载。
public class Sample{
    private final static Logger LOGGER = LoggerFactory.getLogger(Sample.class);

    private static String BUCKET_NAME   = "bucket-name";
    private static String ACCESS_KEY    = "access_key_id";
    private static String SECRET_KEY    = "secret_access_key";
    private static String KEY_NAME      = "/dev/report/余额月报_201705.csv";
    private static String FILE_NAME     = "/web/files/report/余额月报_201705.csv";

    public static void main(String[] args){
        //初始化AmazonS3
        AmazonS3 s3client = new AmazonS3Client(new BasicAWSCredentials(ACCESS_KEY,SECRET_KEY));
        Region usWest2 = Region.getRegion(Regions.CN_NORTH_1);
        s3client.setRegion(usWest2);
        PutObjectResult result = null;
        //上传文件
        try {
            File file = new File(FILE_NAME);
            LOGGER.debug("Uploading a new object:" + file.getName() + " to S3 from a file\n");
            result = s3client.putObject(new PutObjectRequest(
                    BUCKET_NAME, KEY_NAME, FILE_NAME));
        } catch (AmazonServiceException ase) {
            LOGGER.error(ase);
        } catch (AmazonClientException ace) {
            LOGGER.error(ace);
        }
    }
}

S3还提供了InputStream 上传对象,但是官方不建议使用InputStream 方式上传,容易引起OOM,建议采用本地生成临时文件上传文件的形式上传对象。

0x3_3 获取对象列表

public class Sample{

    private static String BUCKET_NAME   = "bucket-name";
    private static String ACCESS_KEY    = "access_key_id";
    private static String SECRET_KEY    = "secret_access_key";
    private static String KEY_NAME      = "/dev/report/余额月报_201705.csv";
    private static String FILE_NAME     = "/web/files/report/余额月报_201705.csv";

    public static void main(String[] args){
        //初始化AmazonS3
        AmazonS3 s3client = new AmazonS3Client(new BasicAWSCredentials(ACCESS_KEY,SECRET_KEY));
        Region usWest2 = Region.getRegion(Regions.CN_NORTH_1);
        s3client.setRegion(usWest2);
        //获取所有对象
        ObjectListing objects = s3client.listObjects(BUCKET_NAME);
        do {
            for (S3ObjectSummary objectSummary : objects.getObjectSummaries()) {
                System.out.println("Object: " + objectSummary.getKey());
            }
            objects = s3client.listNextBatchOfObjects(objects);
        } while (objects.isTruncated());    
    }
}

0x3_4 获取对象

获取(下载)对象,可以获取对象所有元数据和流,建议先读取流内容,再处理其他逻辑,因为获取S3数据时,在读取或关闭输入流之前,网络连接一直保持打开状态。

下载对象:

  1. 创建 AmazonS3Client 类的实例。
  2. 执行 AmazonS3Client.getObject() 方法之一。通过创建 GetObjectRequest 类传入存储桶 键名版本ID)。
  3. 对返回的对象执行 getObjectContent() 方法之一以获取关于对象数据的流,并处理响应。
public class Sample{
    private final static Logger LOGGER = LoggerFactory.getLogger(Sample.class);

    private static String BUCKET_NAME   = "bucket-name";
    private static String ACCESS_KEY    = "access_key_id";
    private static String SECRET_KEY    = "secret_access_key";
    private static String KEY_NAME      = "/dev/report/余额月报_201705.csv";
    private static String FILE_NAME     = "/web/files/report/余额月报_201705.csv";

    public static void main(String[] args){
        //初始化AmazonS3
        AmazonS3 s3client = new AmazonS3Client(new BasicAWSCredentials(ACCESS_KEY,SECRET_KEY));
        Region usWest2 = Region.getRegion(Regions.CN_NORTH_1);
        s3client.setRegion(usWest2);
        PutObjectResult result = null;
        //获取文件
        try {
            LOGGER.debug("Downloading an object");
            S3Object s3object = s3Client.getObject(new GetObjectRequest(
                    BUCKET_NAME, KEY_NAME));
            LOGGER.debug("Content-Type: "  +
                    s3object.getObjectMetadata().getContentType());
            displayTextInputStream(s3object.getObjectContent());
        } catch (AmazonServiceException ase) {
            LOGGER.error(ase);
        } catch (AmazonClientException ace) {
            LOGGER.error(ace);
        }
    }

    private static void displayTextInputStream(InputStream input) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        LOGGER.debug("---------------Object display start--------------------")
        while (true) {
                String line = reader.readLine();
                if (line == null) break;
                LOGGER.debug("    " + line);
        }
        LOGGER.debug("---------------Object display end--------------------")
    }
}

0x3_5 删除对象

S3提供单个删除和批量删除两种删除操作,操作大同小异,在此以单对象删除为例,批量删除不在累述。删除操作分为开启版本控制的桶删除对象,和未开启版本控制的桶删除对象

无版本控制删除

  1. 创建 AmazonS3Client 类的实例。
  2. 执行 AmazonS3Client.deleteObject 方法之一。可以提供存储桶名称和对象名称作为参数,或在 DeleteObjectRequest 对象中提供相同的信息,然后作为参数传递对象。
public class Sample{
    private final static Logger LOGGER = LoggerFactory.getLogger(Sample.class);

    private static String BUCKET_NAME   = "bucket-name";
    private static String ACCESS_KEY    = "access_key_id";
    private static String SECRET_KEY    = "secret_access_key";
    private static String KEY_NAME      = "/dev/report/余额月报_201705.csv";
    private static String FILE_NAME     = "/web/files/report/余额月报_201705.csv";

    public static void main(String[] args) throws IOException {
        //初始化AmazonS3
        AmazonS3 s3client = new AmazonS3Client(new BasicAWSCredentials(ACCESS_KEY,SECRET_KEY));
        Region usWest2 = Region.getRegion(Regions.CN_NORTH_1);
        s3client.setRegion(usWest2);
        PutObjectResult result = null;
        //删除文件
        try {
            LOGGER.debug("Delete an object");
            s3Client.deleteObject(new DeleteObjectRequest(BUCKET_NAME, KEY_NAME));
        } catch (AmazonServiceException ase) {
            LOGGER.error(ase);
        } catch (AmazonClientException ace) {
            LOGGER.error(ace);
        }
    }
}

含版本控制的删除版本

  1. 创建 AmazonS3Client 类的实例。
  2. 对存储桶启用版本控制功能。
  3. 使用 deleteVersion 方法删除示例对象。DeleteVersionRequest 类将指定对象键名称和版本 ID。
public class Sample{
    private final static Logger LOGGER = LoggerFactory.getLogger(Sample.class);

    private static String BUCKET_NAME   = "bucket-name";
    private static String ACCESS_KEY    = "access_key_id";
    private static String SECRET_KEY    = "secret_access_key";
    private static String KEY_NAME      = "/dev/report/余额月报_201705.csv";
    private static String FILE_NAME     = "/web/files/report/余额月报_201705.csv";

    public static void main(String[] args) throws IOException {
        //初始化AmazonS3
        AmazonS3 s3client = new AmazonS3Client(new BasicAWSCredentials(ACCESS_KEY,SECRET_KEY));
        Region usWest2 = Region.getRegion(Regions.CN_NORTH_1);
        s3client.setRegion(usWest2);
        PutObjectResult result = null;
        //删除文件
        try {
            LOGGER.debug("Delete an object");
            //开启版本控制
            enableVersioningOnBucket(s3Client, BUCKET_NAME);
            //上传一个对象并获取版本号
            String versionId = putAnObject(keyName);

            s3Client.deleteVersion(new DeleteVersionRequest(BUCKET_NAME, KEY_NAME, versionId));
        } catch (AmazonServiceException ase) {
            LOGGER.error(ase);
        } catch (AmazonClientException ace) {
            LOGGER.error(ace);
        }
    }

    //开启版本控制
    private static void enableVersioningOnBucket(AmazonS3Client s3client,String bucketName) {

        BucketVersioningConfiguration config = new BucketVersioningConfiguration()
                            .withStatus(BucketVersioningConfiguration.ENABLED);
        SetBucketVersioningConfigurationRequest setBucketVersioningConfigurationRequest = 
                                new SetBucketVersioningConfigurationRequest(bucketName, config);
        s3client.setBucketVersioningConfiguration(setBucketVersioningConfigurationRequest);
    }

    private static String putAnObject(String keyName) {
        String content = "This is the content body!";
        String key = "ObjectToDelete-" + new Random().nextInt();
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setHeader("Subject", "Content-As-Object");
        metadata.setHeader("Content-Length", content.length());
        InputStream inputStream = new ByteArrayInputStream(content.getBytes());
        PutObjectRequest request = new PutObjectRequest(bucketName, key, inputStream, metadata)
                                            .withCannedAcl(CannedAccessControlList.AuthenticatedRead);
        PutObjectResult response = s3Client.putObject(request);
        return response.getVersionId();
    }

}

0x4 参考文献

0x5 关于我

  • @Author:Zemo
  • @Email:zemochen#126.com
  • 欢迎转载,让更多的人学到东西
  • 2
    点赞
  • 0
    评论
  • 5
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值