在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.getSimplifiedObjectMeta
或OSSClient.getObjectMetadata
。getSimplifiedObjectMeta
只能获取文件的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名称采用的编码方式,目前支持 | 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进行编码,目前支持 | 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