AWS S3与Java
1. 简介
在本教程中,我们将学习如何通过 Java 以编程方式与 Amazon S3(简单存储服务)存储系统进行交互。
请记住,S3 的结构非常简单;每个存储桶可以存储任意数量的对象,可以使用 SOAP 接口或 REST 样式的 API 访问这些对象。
展望未来,我们将使用适用于 Java 的 AWS 开发工具包来创建、列出和删除 S3 存储桶。我们还将上传、列出、下载、复制、移动、重命名和删除这些存储桶中的对象。
2. Maven依赖
在开始之前,我们需要在我们的项目中声明 AWS 开发工具包依赖项:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.163</version>
</dependency>
要查看最新版本,我们可以查看Maven Central 。
3. 先决条件
要使用 AWS 开发工具包,我们需要一些东西:
- **AWS 帐户:**我们需要一个 Amazon Web Services 帐户。如果我们没有,我们可以继续创建一个帐户 。
- **AWS 安全凭证:**这些是我们的访问密钥,允许我们以编程方式调用 AWS API 操作。我们可以通过两种方式获取这些凭证,一种是使用来自安全凭证页面的访问密钥部分 的 AWS 根账户凭证,另一种是使用来自IAM 控制台的 IAM 用户凭证。
- **选择 AWS 区域:**我们还必须选择要存储 Amazon S3 数据的 AWS 区域。请记住,S3 存储价格因地区而异。有关更多详细信息,请访问官方文档 。在本教程中,我们将使用美国东部(俄亥俄州,区域us-east-2)。
4. 创建客户端连接
首先,我们需要创建一个客户端连接来访问 Amazon S3 Web 服务。为此,我们将使用AmazonS3接口:
AWSCredentials credentials = new BasicAWSCredentials(
"<AWS accesskey>",
"<AWS secretkey>"
);
然后我们将配置客户端:
AmazonS3 s3client = AmazonS3ClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(Regions.US_EAST_2)
.build();
5. Amazon S3 存储桶操作
5.1. 创建存储桶
请务必注意,存储桶命名空间由系统的所有用户共享。因此,我们的存储桶名称在 Amazon S3 中的所有现有存储桶名称中必须是唯一的(稍后我们将了解如何检查它)。
另外,按照官方文档 的规定,Bucket 名称必须符合以下要求:
- 名称不应包含下划线
- 名称长度应介于 3 到 63 个字符之间
- 名称不应以破折号结尾
- 名称不能包含相邻句点
- 名称不能在句点旁边包含破折号(例如,“my-.bucket.com”和“my.-bucket”无效)
- 名称不能包含大写字符
现在让我们创建一个存储桶:
String bucketName = "blogdemo-bucket";
if(s3client.doesBucketExist(bucketName)) {
LOG.info("Bucket name is not available."
+ " Try again with a different Bucket name.");
return;
}
s3client.createBucket(bucketName);
这里我们使用的是我们在上一步中创建的s3client 。在创建存储桶之前,我们必须使用*doBucketExist()方法检查存储桶名称是否可用。如果名称可用,那么我们将使用createBucket()*方法。
5.2. 列出存储桶
现在我们已经创建了一些存储桶,让我们使用*listBuckets()*方法打印 S3 环境中所有可用存储桶的列表。此方法将返回所有存储桶的列表:
List<Bucket> buckets = s3client.listBuckets();
for(Bucket bucket : buckets) {
System.out.println(bucket.getName());
}
这将列出我们 S3 环境中存在的所有存储桶:
blogdemo-bucket
blogdemo-bucket-test2
elasticbeanstalk-us-east-2
5.3. 删除存储桶
**在我们删除它之前确保我们的存储桶是空的很重要。**否则会抛出异常。另外,请注意,只有存储桶的所有者才能删除它,而不管其权限如何(访问控制策略):
try {
s3client.deleteBucket("blogdemo-bucket-test2");
} catch (AmazonServiceException e) {
System.err.println("e.getErrorMessage());
return;
}
6. Amazon S3 对象操作
Amazon S3 存储桶中的文件或数据集合称为对象。我们可以对对象执行多种操作,例如上传、列出、下载、复制、移动、重命名和删除。
6.1. 上传对象
上传对象是一个非常简单的过程。我们将使用*putObject()*方法,它接受三个参数:
- bucketName:我们要上传对象的存储桶名称
- key:这是文件的完整路径
- file:包含要上传的数据的实际文件
s3client.putObject(
bucketName,
"Document/hello.txt",
new File("/Users/user/Document/hello.txt")
);
6.2. 列出对象
我们将使用*listObjects()*方法列出 S3 存储桶中的所有可用对象:
ObjectListing objectListing = s3client.listObjects(bucketName);
for(S3ObjectSummary os : objectListing.getObjectSummaries()) {
LOG.info(os.getKey());
}
调用s3client对象的listObjects()方法将产生ObjectListing对象,该对象可用于获取指定存储桶中所有对象摘要的列表。我们只是在这里打印密钥,但还有一些其他选项可用,如大小、所有者、上次修改时间、存储类等。
现在将打印我们存储桶中所有对象的列表:
Document/hello.txt
6.3. 下载对象
要下载对象,我们将首先使用s3client上的getObject()方法,该方法将返回一个S3Object对象。一旦我们得到这个,我们将调用它的getObjectContent()来获得一个S3ObjectInputStream对象,它的行为就像一个传统的 Java InputStream:
S3Object s3object = s3client.getObject(bucketName, "picture/pic.png");
S3ObjectInputStream inputStream = s3object.getObjectContent();
FileUtils.copyInputStreamToFile(inputStream, new File("/Users/user/Desktop/hello.txt"));
在这里,我们使用 Apache Commons 的FileUtils.copyInputStreamToFile()方法。我们还可以访问这篇 Blogdemo 文章 来探索将InputStream转换为File 的其他方法。
6.4. 复制、重命名和移动对象
我们可以通过调用 s3client 上的*copyObject()*方法来复制对象,该方法接受四个参数:
- 源存储桶名称
- 源存储桶中的对象键
- 目标存储桶名称(可以与源相同)
- 目标存储桶中的对象键
s3client.copyObject(
"blogdemo-bucket",
"picture/pic.png",
"blogdemo-bucket2",
"document/picture.png"
);
注意:我们可以结合使用*copyObject()方法和deleteObject()*来执行移动和重命名任务。这将涉及首先复制对象,然后将其从旧位置删除。
6.5. 删除对象
要删除对象,我们将调用s3client 上的*deleteObject()*方法并传递存储桶名称和对象键:
s3client.deleteObject("blogdemo-bucket","picture/pic.png");
6.6. 删除多个对象
要一次删除多个对象,我们将首先创建DeleteObjectsRequest对象并将存储桶名称传递给其构造函数。然后我们将传递一个包含我们要删除的所有对象键的数组。
一旦我们有了这个DeleteObjectsRequest对象,我们就可以将它作为参数传递给 s3client 的*deleteObjects()*方法。如果成功,它将删除我们提供的所有对象:
String objkeyArr[] = {
"document/hello.txt",
"document/pic.png"
};
DeleteObjectsRequest delObjReq = new DeleteObjectsRequest("blogdemo-bucket")
.withKeys(objkeyArr);
s3client.deleteObjects(delObjReq);