首页 > 编程语言 >Java 使用阿里云OSS服务

Java 使用阿里云OSS服务

时间:2023-09-13 15:32:20浏览次数:44  
标签:Java String OSS Object ossClient OSSClient 阿里 println out


在OSS中,用户可以通过一系列的接口管理存储空间(Bucket)中的文件(Object),比如SetObjectAcl,GetObjectAcl,ListObjects,DeleteObject,CopyObject,DoesObjectExist等。Object的名字又称为key或object key。下文详细的介绍了使用java如何操作阿里云的OSS服务。

Object是否存在

通过OSSClient.doesObjectExist判断文件(object)是否存在。


1. // endpoint以杭州为例,其它region请按实际情况填写
2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
3. // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
4. String accessKeyId = "<yourAccessKeyId>";
5. String accessKeySecret = "<yourAccessKeySecret>";
6. 
7. // 创建OSSClient实例
8. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
9. 
10. // Object是否存在
11. boolean found = ossClient.doesObjectExist("<bucketName>", "<key>")
12. 
13. // 关闭client
14. ossClient.shutdown();

Object ACL

Object有四种访问权限:Default(默认),Private(私有读写), PublicRead(公共读私有写), PublicReadWrite(公共读写),含义如下:

权限

描述

默认

Objec是遵循Bucket的读写权限,即Bucket是什么权限,Object就是什么权限,Object的默认权限

私有读写

Object是私有资源,即只有该Object的Owner拥有该Object的读写权限,其他的用户没有权限操作该Object

公共读私有写

Object是公共读资源,即非Object Owner只有Object的读权限,而Object Owner拥有该Object的读写权限

公共读写

Object是公共读写资源,即所有用户拥有对该Object的读写权限

Object的权限优先级高于Bucket。例如Bucket是private的,而Object ACL是公共读写,则访问这个Object时,先判断Object的ACL,所有用户都拥有这个Object的访问权限,即使这个Bucket是private。如果某个Object从来没设置过ACL,则访问权限遵循Bucket ACL。

设置Object ACL

您可以通过OSSClient.setObjectAcl设置Object的权限。

权限

Java SDK对应值

私有读写

CannedAccessControlList.Private

公共读私有写

CannedAccessControlList.PublicRead

公共读写

CannedAccessControlList.PublicReadWrite

下面代码为Object设置ACL:


1. // endpoint以杭州为例,其它region请按实际情况填写
2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
3. // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
4. String accessKeyId = "<yourAccessKeyId>";
5. String accessKeySecret = "<yourAccessKeySecret>";
6. 
7. // 创建OSSClient实例
8. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
9. 
10. // 设置Object权限
11. ossClient.setObjectAcl("<bucketName>", "<key>", CannedAccessControlList.PublicRead)
12. 
13. // 关闭client
14. ossClient.shutdown();

获取Object ACL

您可以通过OSSClient.getObjectAcl获取Object的权限。


1. // endpoint以杭州为例,其它region请按实际情况填写
2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
3. // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
4. String accessKeyId = "<yourAccessKeyId>";
5. String accessKeySecret = "<yourAccessKeySecret>";
6. 
7. // 创建OSSClient实例
8. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
9. 
10. //读取Object ACL
11. ObjectAcl objectAcl = ossClient.getObjectAcl("<bucketName>", "<key>");
12. System.out.println(objectAcl.getPermission().toString());
13. 
14. // 关闭client
15. ossClient.shutdown();

获取文件元信息(Object Meta)

文件元信息(Object Meta),是对用户上传到OSS的文件的属性描述,分为两种:HTTP标准属性(HTTP Headers)和User Meta(用户自定义元信息)。 文件元信息可以在各种方式上传或者拷贝文件时进行设置。更多文件元信息的介绍,请参看文件元信息

获取文件元信息可以使用OSSClient.getSimplifiedObjectMetaOSSClient.getObjectMetadatagetSimplifiedObjectMeta只能获取文件的ETag、Size(文件大小)、 LastModified(最后修改时间);getObjectMetadata能获取文件的全部元数据。getSimplifiedObjectMeta更轻量、更快。


1. // endpoint以杭州为例,其它region请按实际情况填写
2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
3. // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
4. String accessKeyId = "<yourAccessKeyId>";
5. String accessKeySecret = "<yourAccessKeySecret>";
6. 
7. // 创建OSSClient实例
8. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
9. 
10. // 获取文件的部分元信息
11. SimplifiedObjectMeta objectMeta = ossClient.getSimplifiedObjectMeta("<bucketName>", "<key>");
12. System.out.println(objectMeta.getSize());
13. System.out.println(objectMeta.getETag());
14. System.out.println(objectMeta.getLastModified());
15. 
16. // 获取文件的全部元信息
17. ObjectMetadata metadata = ossClient.getObjectMetadata("<bucketName>", "<key>");
18. System.out.println(metadata.getContentType());
19. System.out.println(metadata.getLastModified());
20. System.out.println(metadata.getExpirationTime()); 
21. 
22. // 关闭client
23. ossClient.shutdown();

列出存储空间中的文件

可以通过OSSClient.listObjects列出bucket里的Objects。listObjects有三类参数格式:

  • ObjectListing listObjects(String bucketName)
  • ObjectListing listObjects(String bucketName, String prefix)
  • ObjectListing listObjects(ListObjectsRequest listObjectsRequest)

前两类称为简单列举,最多返回100条object,参数prefix是指定返回Object的前缀。最后一类提供多种过滤功能,可以实现灵活的查询功能。

ObjectListing的参数如下:

参数

含义

方法

ObjectSummaries

限定返回的object meta。

List<OSSObjectSummary> getObjectSummaries()

Prefix

本次查询结果的开始前缀。

String getPrefix()

Delimiter

是一个用于对Object名字进行分组的字符。

String getDelimiter()

Marker

标明这次List Object的起点。

String getMarker()

MaxKeys

响应请求内返回结果的最大数目。

int getMaxKeys()

NextMarker

下一次List Object的起点。

String getNextMarker()

IsTruncated

指明是否所有的结果都已经返回。

boolean isTruncated()

CommonPrefixes

如果请求中指定了delimiter参数,则返回的包含CommonPrefixes元素。该元素标明以delimiter结尾,并有共同前缀的object的集合。

List<String> getCommonPrefixes()

EncodingType

指明返回结果中编码使用的类型。

String getEncodingType()

提示:

  • listObjects的完整代码请参考:GitHub

简单列举

列举出Bucket下的Object,最多100条object。


1. // endpoint以杭州为例,其它region请按实际情况填写
2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
3. // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
4. String accessKeyId = "<yourAccessKeyId>";
5. String accessKeySecret = "<yourAccessKeySecret>";
6. 
7. // 创建OSSClient实例
8. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
9. 
10. // 列举Object
11. ObjectListing objectListing = ossClient.listObjects("<bucketName>", "<KeyPrifex>");
12. List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
13. for (OSSObjectSummary s : sums) {
14.  System.out.println("\t" + s.getKey());
15. }
16. 
17. // 关闭client
18. ossClient.shutdown();

列举出Bucket下的指定前缀的Object,最多100条object。


1. ObjectListing objectListing = ossClient.listObjects("<bucketName>", "<KeyPrifex>");
2. List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
3. for (OSSObjectSummary s : sums) {
4.  System.out.println("\t" + s.getKey());
5. }

通过ListObjectsRequest列出文件

可以通过设置ListObjectsReques的参数实现各种灵活的查询功能。ListObjectsReques的可设置的参数如下:

参数

作用

方法

Prefix

限定返回的object key必须以prefix作为前缀。

setPrefix(String prefix)

Delimiter

是一个用于对Object名字进行分组的字符。所有名字包含指定的前缀且第一次出现delimiter字符之间的object作为一组元素——CommonPrefixes。

setDelimiter(String delimiter)

Marker

设定结果从marker之后按字母排序的第一个开始返回。

setMarker(String marker)

MaxKeys

限定此次返回object的最大数,如果不设定,默认为100,max-keys取值不能大于1000。

setMaxKeys(Integer maxKeys)

EncodingType

请求响应体中Object名称采用的编码方式,目前支持url

setEncodingType(String encodingType)

指定最大返回条数


1. // endpoint以杭州为例,其它region请按实际情况填写
2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
3. // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
4. String accessKeyId = "<yourAccessKeyId>";
5. String accessKeySecret = "<yourAccessKeySecret>";
6. 
7. // 创建OSSClient实例
8. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
9. 
10. final int maxKeys = 200;
11. // 列举Object
12. ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest("<bucketName>").withMaxKeys(maxKeys));
13. List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
14. for (OSSObjectSummary s : sums) {
15.  System.out.println("\t" + s.getKey());
16. }
17. 
18. // 关闭client
19. ossClient.shutdown();

返回指定前缀的object

最多返回100条。


1. final String keyPrefix = "<keyPrefix>"
2. 
3. ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest("<bucketName>").withPrefix(keyPrefix));
4. List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
5. for (OSSObjectSummary s : sums) {
6.  System.out.println("\t" + s.getKey());
7. }

从指定Object后返回

不包括指定的Object,最多返回100条。


1. final String keyMarker = "<keyMarker>"
2. 
3. ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest("<bucketName>").withMarker(keyMarker));
4. List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
5. for (OSSObjectSummary s : sums) {
6.  System.out.println("\t" + s.getKey());
7. }

分页获取所有Object

分页获取所有Object,每页maxKeys条Object。


1. final int maxKeys = 200;
2. String nextMarker = null;
3. do {
4.  objectListing = ossClient.listObjects(new ListObjectsRequest("<bucketName>").withMarker(nextMarker).withMaxKeys(maxKeys));
5. 
6.  List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
7.  for (OSSObjectSummary s : sums) {
8.  System.out.println("\t" + s.getKey());
9.  }
10. 
11.  nextMarker = objectListing.getNextMarker();
12. 
13. } while (objectListing.isTruncated());

分页获取所有特定Object后的Object

分页获取所有特定Object后的Object,每页maxKeys条Object。

分页所有获取指定前缀的Object

1. final int maxKeys = 200;
2. String nextMarker = "<nextMarker>";
3. do {
4.  objectListing = ossClient.listObjects(new ListObjectsRequest("<bucketName>").withMarker(nextMarker).withMaxKeys(maxKeys));
5. 
6.  List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
7.  for (OSSObjectSummary s : sums) {
8.  System.out.println("\t" + s.getKey());
9.  }
10. 
11.  nextMarker = objectListing.getNextMarker();
12. 
13. } while (objectListing.isTruncated());

分页所有获取指定前缀的Object,每页maxKeys条Object。


1. final int maxKeys = 200;
2. final String keyPrefix = "<keyPrefix>";
3. String nextMarker = "<nextMarker>";
4. 
5. do {
6.  objectListing = ossClient.listObjects(new ListObjectsRequest("<bucketName>").
7.  withPrefix(keyPrefix).withMarker(nextMarker).withMaxKeys(maxKeys));
8. 
9.  List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
10.  for (OSSObjectSummary s : sums) {
11.  System.out.println("\t" + s.getKey());
12.  }
13. 
14.  nextMarker = objectListing.getNextMarker();
15. 
16. } while (objectListing.isTruncated());

指定Object名字编码

如果Object名字含有特殊字符,如 ' " & < >中文 等,需要进行编码传输。OSS目前支持 url

模拟文件夹功能

1. final int maxKeys = 200;
2. final String keyPrefix = "<keyPrefix>";
3. String nextMarker = "<nextMarker>"; 
4. ObjectListing objectListing;
5. 
6. do {
7.  ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
8.  listObjectsRequest.setPrefix(keyPrefix);
9.  listObjectsRequest.setMaxKeys(maxKeys);
10.  listObjectsRequest.setMarker(nextMarker);
11. 
12.  // 指定Object名称编码传输
13.  listObjectsRequest.setEncodingType("url");
14. 
15.  objectListing = ossClient.listObjects(listObjectsRequest);
16. 
17.  // Object解码
18.  for (OSSObjectSummary objectSummary: objectListing.getObjectSummaries()) {
19.  System.out.println("Key:" + URLDecoder.decode(objectSummary.getKey(), "UTF-8"));
20.  }
21. 
22.  // CommonPrefixe解码
23.  for (String commonPrefixes: objectListing.getCommonPrefixes()) {
24.  System.out.println("CommonPrefixes:" + URLDecoder.decode(commonPrefixes, "UTF-8"));
25.  }
26. 
27.  // NextMarker解码
28.  if (objectListing.getNextMarker() != null) {
29.  nextMarker = URLDecoder.decode(objectListing.getNextMarker(), "UTF-8");
30.  }
31. } while (objectListing.isTruncated());

OSS是没有文件夹这个概念的,所有元素都是以Object来存储。创建模拟文件夹本质上来说是创建了一个size为0的Object。对于这个Object可以上传下载,只是控制台会对以”/“结尾的Object以文件夹的方式展示。

您可以通过 Delimiter 和 Prefix 参数的配合模拟出文件夹功能。Delimiter 和 Prefix 的组合效果是这样的:

  • 如果把 Prefix 设为某个文件夹名,就可以罗列以此 Prefix 开头的文件,即该文件夹下递归的所有的文件和子文件夹(目录)。文件名在Contents中显示。
  • 如果再把 Delimiter 设置为 “/” 时,返回值就只罗列该文件夹下的文件和子文件夹(目录),该文件夹下的子文件名(目录)返回在 CommonPrefixes 部分,子文件夹下递归的文件和文件夹不被显示。

提示:

假设Bucket中有4个文件: oss.jpg , fun/test.jpg , fun/movie/001.avi , fun/movie/007.avi , “/” 作为文件夹的分隔符。下面的示例展示了如何模拟文件夹功能。

列出存储空间内所有文件

当我们需要获取存储空间下的所有文件时,可以这样写:


1. // 构造ListObjectsRequest请求
2. ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
3. 
4. // 列出Object 
5. ObjectListing listing = ossClient.listObjects(listObjectsRequest);
6. 
7. // 遍历所有Object
8. System.out.println("Objects:");
9. for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
10.  System.out.println(objectSummary.getKey());
11. }
12. 
13. // 遍历所有CommonPrefix
14. System.out.println("CommonPrefixs:");
15. for (String commonPrefix : listing.getCommonPrefixes()) {
16.  System.out.println(commonPrefix);
17. }

输出:


1. Objects:
2. fun/movie/001.avi
3. fun/movie/007.avi
4. fun/test.jpg
5. oss.jpg
6. 
7. CommonPrefixs:

递归列出目录下所有文件

我们可以通过设置 Prefix 参数来获取某个目录(fun/)下所有的文件:


1. // 构造ListObjectsRequest请求
2. ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
3. listObjectsRequest.setPrefix("fun/");
4. 
5. // 递归列出fun目录下的所有文件
6. ObjectListing listing = ossClient.listObjects(listObjectsRequest);
7. 
8. // 遍历所有Object
9. System.out.println("Objects:");
10. for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
11.  System.out.println(objectSummary.getKey());
12. }
13. 
14. // 遍历所有CommonPrefix
15. System.out.println("\nCommonPrefixs:");
16. for (String commonPrefix : listing.getCommonPrefixes()) {
17.  System.out.println(commonPrefix);
18. }

输出:


1. Objects:
2. fun/movie/001.avi
3. fun/movie/007.avi
4. fun/test.jpg
5. CommonPrefixs:


列出目录下的文件和子目录

在 Prefix 和 Delimiter 结合的情况下,可以列出目录(fun/)下的文件和子目录:


1. // 构造ListObjectsRequest请求
2. ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
3. 
4. // "/" 为文件夹的分隔符
5. listObjectsRequest.setDelimiter("/");
6. 
7. // 列出fun目录下的所有文件和文件夹
8. listObjectsRequest.setPrefix("fun/");
9. 
10. ObjectListing listing = ossClient.listObjects(listObjectsRequest);
11. 
12. // 遍历所有Object
13. System.out.println("Objects:");
14. for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
15.  System.out.println(objectSummary.getKey());
16. }
17. 
18. // 遍历所有CommonPrefix
19. System.out.println("\nCommonPrefixs:");
20. for (String commonPrefix : listing.getCommonPrefixes()) {
21.  System.out.println(commonPrefix);
22. }

输出:


1. Objects:
2. fun/test.jpg
3. 
4. CommonPrefixs:
5. fun/movie/

提示:

  • 返回的结果中, ObjectSummaries 的列表中给出的是fun目录下的文件。
  • 而 CommonPrefixs 的列表中给出的是fun目录下的所有子文件夹。可以看出 fun/movie/001.avi , fun/movie/007.avi 两个文件并没有被列出来,因为它们属于fun文件夹下的movie目录。

删除文件

删除单个文件:

您可以通过OSSClient.deleteObject删除单个文件。


1. // endpoint以杭州为例,其它region请按实际情况填写
2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
3. // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
4. String accessKeyId = "<yourAccessKeyId>";
5. String accessKeySecret = "<yourAccessKeySecret>";
6. 
7. // 创建OSSClient实例
8. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
9. 
10. // 删除Object
11. ossClient.deleteObject("<bucketName>", "<key>");
12. 
13. // 关闭client
14. ossClient.shutdown();

删除多个文件:

您可以通过OSSClient.deleteObjects批量删除文件。


1. public DeleteObjectsResult deleteObjects(DeleteObjectsRequest deleteObjectsRequest)

每次最多删除1000个Object,并提供两种返回模式:详细(verbose)模式和简单(quiet)模式:

  • 详细模式:返回的成功删除Object的结果,即DeleteObjectsResult.getDeletedObjects,默认模式;
  • 简单模式:返回的删除过程中出错的Object结果,即DeleteObjectsResult.getDeletedObjects。

DeleteObjectsRequest可设置参数如下:

参数

作用

方法

Keys

需要删除的Objects

setKeys(List<String>)

Quiet

返回模式,默认详细模式;true简单模式,false详细模式

setQuiet(boolean)

EncodingType

指定对返回的Key进行编码,目前支持url

setEncodingType(String)

DeleteObjectsResult的参数如下:

参数

含义

方法

deletedObjects

删除结果,详细模式时成功删除的objects,简单模式时删除失败的objects

List<String> getDeletedObjects()

EncodingType

deletedObjects中Key的进行编码,为空没有编码

getEncodingType()

1. // endpoint以杭州为例,其它region请按实际情况填写
2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
3. // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
4. String accessKeyId = "<yourAccessKeyId>";
5. String accessKeySecret = "<yourAccessKeySecret>";
6. 
7. // 创建OSSClient实例
8. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
9. 
10. // 删除Objects
11. List<String> keys = new ArrayList<String>();
12. keys.add("key0");
13. keys.add("key1");
14. keys.add("key2");
15. 
16. DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest("<bucketName>").withKeys(keys));
17. List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
18. 
19. // 关闭client
20. ossClient.shutdown();

提示:

  • 批量删除文件的完整代码请参考:GitHub

拷贝文件

在同一个区域(杭州,深圳,青岛等)中,可以将Object从一个Bucket复制到另外一个Bucket。您可以通过OSSClient.copyObject

  • CopyObjectResult copyObject(String sourceBucketName, String sourceKey, String destinationBucketName, String destinationKey)
  • CopyObjectResult copyObject(CopyObjectRequest copyObjectRequest)

第一个方法指定源Bucket/Key和目标源Bucket/Key,目标object的内容和元数据与源object相同,称为简单拷贝。第二个方法允许指定目标文件的原因数据、允许指定拷贝的限制条件。如果拷贝操作的源Object地址和目标Object地址相同,则直接替换源Object的meta信息。

CopyObjectRequest可设置参数如下:

参数

作用

方法

sourceBucketName

源Object所在的Bucket的名称

setSourceBucketName(String sourceBucketName)

sourceKey

源Object的Key

setSourceKey(String sourceKey)

destinationBucketName

目标Object所在的Bucket的名称

setDestinationBucketName(String destinationBucketName)

destinationKey

目标Object的Key

setDestinationKey(String destinationKey)

newObjectMetadata

目标Object的元信息

setNewObjectMetadata(ObjectMetadata newObjectMetadata)

matchingETagConstraints

拷贝的限制条件,如果源Object的ETAG值和提供的ETAG相等,则执行拷贝操作;否则返回错误

setMatchingETagConstraints(List<String> matchingETagConstraints)

nonmatchingEtagConstraints

拷贝的限制条件,如果源Object的ETAG值和用户提供的ETAG不相等,则执行拷贝操作;否则返回错误

setNonmatchingETagConstraints(List<String> nonmatchingEtagConstraints)

unmodifiedSinceConstraint

拷贝的限制条件,如果传入参数中的时间等于或者晚于文件实际修改时间,则正常拷贝;否则返回错误

setUnmodifiedSinceConstraint(Date unmodifiedSinceConstraint)

modifiedSinceConstraint

拷贝的限制条件,如果源Object自从用户指定的时间以后被修改过,则执行拷贝操作;否则返回错误

setModifiedSinceConstraint(Date modifiedSinceConstraint)

CopyObjectRequest的参数如下:

参数

含义

方法

etag

OSS Object唯一性标志

String getETag()

lastModified

Object最后修改时间

Date getLastModified()

注意:

  • 用户需要有源Object的操作权限,否则会无法完成操作。
  • 该操作不支持跨Region拷贝数据。比如:不支持将杭州Bucket里的Object拷贝到青岛。
  • 该操作支持的最大Object大小为1GB。

简单拷贝

1. // endpoint以杭州为例,其它region请按实际情况填写
2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
3. // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
4. String accessKeyId = "<yourAccessKeyId>";
5. String accessKeySecret = "<yourAccessKeySecret>";
6. 
7. // 创建OSSClient实例
8. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
9. 
10. // 拷贝Object
11. CopyObjectResult result = ossClient.copyObject("<srcBucketName>", "<srcKey>", "<destBucketName>", "<destKey>");
12. System.out.println("ETag: " + result.getETag() + " LastModified: " + result.getLastModified());
13. 
14. // 关闭client
15. ossClient.shutdown();

通过CopyObjectRequest拷贝

也可以通过 CopyObjectRequest 实现Object的拷贝:

拷贝大文件

1. // endpoint以杭州为例,其它region请按实际情况填写
2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
3. // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
4. String accessKeyId = "<yourAccessKeyId>";
5. String accessKeySecret = "<yourAccessKeySecret>";
6. 
7. // 创建OSSClient实例
8. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
9. 
10. // 创建CopyObjectRequest对象
11. CopyObjectRequest copyObjectRequest = new CopyObjectRequest(srcBucketName, srcKey, destBucketName, destKey);
12. 
13. // 设置新的Metadata
14. ObjectMetadata meta = new ObjectMetadata();
15. meta.setContentType("text/html");
16. copyObjectRequest.setNewObjectMetadata(meta);
17. 
18. // 复制Object
19. CopyObjectResult result = ossClient.copyObject(copyObjectRequest);
20. System.out.println("ETag: " + result.getETag() + " LastModified: " + result.getLastModified());
21. 
22. // 关闭client
23. ossClient.shutdown();

CopyObject只能copy小于1GB的文件,大文件需要使用分片拷贝(Upload Part Copy)。分片拷贝更详细的说明,请参考Upload Part Copy。分片拷贝分为三步:

  • 初始化分片拷贝任务
OSSClient.initiateMultipartUpload
  • 分片拷贝
OSSClient.uploadPartCopy
  • ,除最后一个分片外,其它的分片大小都要大于100KB;
  • 提交分片拷贝任务
OSSClient.completeMultipartUpload

提示:

  • 分片拷贝的完整代码请参考:GitHub
1. String sourceBucketName = "<sourceBucketName>";
2. String sourceKey = "<sourceKey>";
3. String targetBucketName = "<targetBucketName>";
4. String targetKey = "<targetKey>";
5. 
6. // 得到被拷贝object大小
7. ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceKey);
8. long contentLength = objectMetadata.getContentLength();
9. 
10. // 分片大小,10MB
11. long partSize = 1024 * 1024 * 10;
12. 
13. // 计算分块数目
14. int partCount = (int) (contentLength / partSize);
15. if (contentLength % partSize != 0) {
16.  partCount++;
17. }
18. System.out.println("total part count:" + partCount);
19. 
20. // 初始化拷贝任务
21. InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(targetBucketName, targetKey);
22. InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest);
23. String uploadId = initiateMultipartUploadResult.getUploadId();
24. 
25. // 分片拷贝
26. List<PartETag> partETags = new ArrayList<PartETag>();
27. for (int i = 0; i < partCount; i++) {
28.  // 计算每个分块的大小
29.  long skipBytes = partSize * i;
30.  long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes;
31. 
32.  // 创建UploadPartCopyRequest
33.  UploadPartCopyRequest uploadPartCopyRequest = 
34.  new UploadPartCopyRequest(sourceBucketName, sourceKey, targetBucketName, targetKey);
35.  uploadPartCopyRequest.setUploadId(uploadId);
36.  uploadPartCopyRequest.setPartSize(size);
37.  uploadPartCopyRequest.setBeginIndex(skipBytes);
38.  uploadPartCopyRequest.setPartNumber(i + 1);
39.  UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest);
40. 
41.  // 将返回的PartETag保存到List中
42.  partETags.add(uploadPartCopyResult.getPartETag());
43. }
44. 
45. // 提交分片拷贝任务
46. CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(
47.  targetBucketName, targetKey, uploadId, partETags);
48. ossClient.completeMultipartUpload(completeMultipartUploadRequest);

提示:

  • 分片拷贝时,可以指定目标object的元信息,通过InitiateMultipartUploadRequest指定;
  • 分片拷贝也支持限定条件,通过UploadPartCopyRequest指定。

解冻归档文件

归档(Archive)类型的Object,解冻之后(Restore)后才能读取。详细说明请参看 归档存储。归档文件的状态变换过程如下:

  • 归档类型的文件初始时处于冷冻状态;
  • 提交解冻(Restore)操作后,服务端执行解冻,文件处于解冻中;
  • 完成解冻后,可以读取Object;
  • 解冻状态默认持续1天,最多延长7天,之后文件又回到冷冻状态。


1. ObjectMetadata objectMetadata = ossClient.getObjectMetadata(bucketName, key);
2. 
3. // check whether the object is archive class
4. StorageClass storageClass = objectMetadata.getObjectStorageClass();
5. if (storageClass == StorageClass.Archive) {
6.  // restore object
7.  ossClient.restoreObject(bucketName, key);
8. 
9.  // wait for restore completed
10.  do {
11.  Thread.sleep(1000);
12.  objectMetadata = ossClient.getObjectMetadata(bucketName, key);
13.  } while (!objectMetadata.isRestoreCompleted());
14. }
15. 
16. // get restored object
17. OSSObject ossObject = ossClient.getObject(bucketName, key);
18. ossObject.getObjectContent().close();

标签:Java,String,OSS,Object,ossClient,OSSClient,阿里,println,out
From: https://blog.51cto.com/u_15936016/7455671

相关文章

  • Java21虚拟线程的注意点
    Java21虚拟线程的注意点ThreadLocal能继续用么?Java开发组设计虚拟线程的时候,原本想去掉对ThreadLocal的支持。但由于使用它的库太多,并且很多为了传参才用,并不是缓存,所以就保持了支持。像隐式传参的这种场景,继续用也没事儿,就是性能有所损耗。(不会影响GC,生命周期随着虚拟线程......
  • IDEA调试Java代码
    配置环境:ImportProjectModule1.打开File->ProjectStructure->Modules2.点击+按钮,选择ImportModule->找到根目录下的appName.iml文件(IML文件的全称是"IntelliJModule",它用于描述项目中的模块(Module)以及这些模块的配置)LocalDebug1.打开Run->EditConfigu......
  • 无涯教程-JavaScript - YIELDDISC函数
    描述YIELDDISC函数返回打折证券的年收益。语法YIELDDISC(settlement,maturity,pr,redemption,[basis])争论Argument描述Required/OptionalSettlement证券的结算日期。证券结算日期是指在发行日期之后将证券交易给买方的日期。RequiredMaturity证券的到期......
  • 【Linux】阿里云linux服务器,开放一个端口
    服务器如何开通一个端口您好,1,首先,如果使用的是云服务器ECS,需要在安全组中放行需要开通的端口,操作方法请参见添加安全组规则。如果使用的是轻量应用服务器,需要在防火墙中放行需要开通的端口,操作方法请参见轻量应用服务器防火墙。2,其次,需要在服务器内部确保对应的服务已经启动,并且......
  • Java百钱百鸡
    /**百钱百鸡练习*需求:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。*百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?*x+y+z=100*5x+3y+z/3=100*0<=x<=20;*0<=y<=33;*0<=z<=100;*第一层循环,用......
  • 无涯教程-JavaScript - YIELD函数
    描述YIELD函数返回定期付息的证券的收益率。使用YIELD计算债券收益率。语法YIELD(settlement,maturity,rate,pr,redemption,frequency,[basis])争论Argument描述Required/OptionalSettlement证券的结算日期。证券结算日期是指在发行日期之后将证券交易给买方......
  • Java多线程____Executors线程池的使用和架构原理
    1.线程池API类型1.创建一个可重用固定线程数的线程池packagecom.frame.base.thread;importjava.util.concurrent.Executors;importjava.util.concurrent.ExecutorService;/***Java线程:线程池*@authorAdministrator*/publicclassTestExecutors{ publicstati......
  • Java网路编程____TCP协议客户端服务器信息交互例子
    packagecom.frame.base.TCP;importjava.io.InputStream;importjava.net.ServerSocket;importjava.net.Socket;publicclassTCPSocketServer{ publicstaticvoidmain(String[]args)throwsException{ /** *启动服务端Soecket注册外放信息交互的端口 */......
  • Java多线程____线程死锁例子
    1:两个任务以相反的顺序申请两个锁,死锁就可能出现2:线程T1获得锁L1,线程T2获得锁L2,然后T1申请获得锁L2,同时T2申请获得锁L1,此时两个线程将要永久阻塞,死锁出现packagecom.zs.test; publicclassDeadLock{ publicstaticStringobjA="objA"; publicstaticStringobjB="ob......
  • Java多线程____生产者与消费者模型
    1.仓库类__:入库和出库的集合 有生产和出货方法packagecom.test.thread;importjava.util.LinkedList;/***@authorAdministrator*仓库类*/publicclassStorage{ //存储集合 privateLinkedList<Object>list=newLinkedList<Object>(); publicvoidruk......