对象管理

更新时间:2025-08-27 10:06:22

WOS Java SDK 提供了丰富的对象管理接口,本文介绍使用此接口管理对象的常见操作。

1. 设置对象属性

您可以通过 WosClient.setObjectMetadata 来设置对象属性,包括对象自定义元数据等信息。以下代码展示了如何设置对象属性:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

SetObjectMetadataRequest request = new SetObjectMetadataRequest("bucketname", "objectname");
request.addUserMetadata("property1", "property-value1");
// 设置自定义元数据
ObjectMetadata metadata = wosClient.setObjectMetadata(request);

System.out.println("\t" + metadata.getUserMetadata("property1"));

2. 获取对象属性

您可以通过 WosClient.getObjectMetadata 来获取对象属性,包括对象长度、对象MIME类型、对象自定义元数据等信息。以下代码展示了如何获取对象属性:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

ObjectMetadata metadata = wosClient.getObjectMetadata("bucketname", "objectname");
System.out.println("\t" + metadata.getContentType());
System.out.println("\t" + metadata.getContentLength());
System.out.println("\t" + metadata.getUserMetadata("property"));

3. 获取对象访问权限

您可以通过 WosClient.getObjectAcl 获取对象的访问权限。以下代码展示如何获取对象访问权限:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

AccessControlList acl = wosClient.getObjectAcl("bucketname", "objectname");
System.out.println(acl);

4. 列举对象

您可以通过 WosClient.listObjects 列举出空间里的对象。

可设置参数

参数 作用 WOS Java SDK对应方法
bucketName 空间名称 ListObjectsRequest.setBucketName
prefix 限定返回的对象名必须带有 prefix 前缀 ListObjectsRequest.setPrefix
marker 列举对象的起始位置,返回列表为对象名按字典序排序后该参数以后的所有对象 ListObjectsRequest.setMarker
maxKeys 列举对象的最大数目,取值范围为1~1000,超出范围时默认1000 ListObjectsRequest.setMaxKeys
delimiter 用于分组对象名的字符。对象名中包含 delimiter 的对象,将对象名(去掉 prefix 后)从首字符到第一个delimiter作为分组 ListObjectsRequest.setDelimiter

简单列举

以下代码展示如何简单列举对象,最多返回1000个对象:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

ObjectListing result = wosClient.listObjects("bucketname");
for(WosObject wosObject : result.getObjects()){
    System.out.println("\t" + wosObject.getObjectKey());
    System.out.println("\t" + wosObject.getOwner());
}

说明:

  • 每次至多返回1000个对象。如果指定空间包含对象数量大于1000,ObjectListing.isTruncated 为 true。可通过 ObjectListing.getNextMarker 获取下次列举起始位置。
  • 若需获取全部对象,可采用分页列举。

指定数目列举

以下代码展示如何指定数目列举对象:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setMaxKeys(100);
ObjectListing result = wosClient.listObjects(request);
for(WosObject wosObject : result.getObjects()){
    System.out.println("\t" + wosObject.getObjectKey());
    System.out.println("\t" + wosObject.getOwner());
}

指定前缀列举

以下代码展示如何指定前缀列举对象:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setMaxKeys(100);
request.setPrefix("prefix");
ObjectListing result = wosClient.listObjects(request);
for(WosObject wosObject : result.getObjects()){
    System.out.println("\t" + wosObject.getObjectKey());
    System.out.println("\t" + wosObject.getOwner());
}

指定起始位置列举

以下代码展示如何指定起始位置列举对象:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setMaxKeys(100);
request.setMarker("test");
ObjectListing result = wosClient.listObjects(request);
for(WosObject wosObject : result.getObjects()){
    System.out.println("\t" + wosObject.getObjectKey());
    System.out.println("\t" + wosObject.getOwner());
}

分页列举全部对象

以下代码展示分页列举全部对象:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setMaxKeys(100);

ObjectListing result;
do{
    result = wosClient.listObjects(request);
    for(WosObject wosObject : result.getObjects()){
        System.out.println("\t" + wosObject.getObjectKey());
        System.out.println("\t" + wosObject.getOwner());
    }
    request.setMarker(result.getNextMarker());
}while(result.isTruncated());

列举文件夹中的所有对象

WOS 本身没有文件夹概念,空间中只存储对象。文件夹对象实际是大小为0且以“/”结尾的对象。以该对象名为前缀即可模拟列举文件夹中对象。以下代码展示如何列举文件夹中的对象:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setPrefix("dir/");
request.setMaxKeys(1000);

ObjectListing result;

do{
    result = wosClient.listObjects(request);
    for (WosObject wosObject : result.getObjects())
    {
        System.out.println("\t" + wosObject.getObjectKey());
        System.out.println("\t" + wosObject.getOwner());
    }
    request.setMarker(result.getNextMarker());
}while(result.isTruncated());

按文件夹分组列举所有对象

以下代码展示如何按文件夹分组,列举空间内所有对象:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setMaxKeys(1000);
// 设置文件夹分隔符"/"
request.setDelimiter("/");
ObjectListing result = wosClient.listObjects(request);
System.out.println("Objects in the root directory:");
for(WosObject wosObject : result.getObjects()){
    System.out.println("\t" + wosObject.getObjectKey());
    System.out.println("\t" + wosObject.getOwner());
}
listObjectsByPrefix(wosClient, request, result);

递归列出子文件夹中对象的函数listObjectsByPrefix的示例代码如下:

static void listObjectsByPrefix(WosClient wosClient, ListObjectsRequest request, ObjectListing result) throws WosException
{
    for(String prefix : result.getCommonPrefixes()){
        System.out.println("Objects in folder [" + prefix + "]:");
        request.setPrefix(prefix);
        result  = wosClient.listObjects(request);
        for(WosObject wosObject : result.getObjects()){
            System.out.println("\t" + wosObject.getObjectKey());
            System.out.println("\t" + wosObject.getOwner());
        }
        listObjectsByPrefix(wosClient, request, result);
    }
}

说明:

  • 以上代码未考虑单个文件夹中对象数超过1000的情况。
  • 由于是需要列举出文件夹中的对象和子文件夹,且文件夹对象总是以“/”结尾,因此递归时 delimiter 总是为/
  • 每次递归的返回结果中,ObjectListing.getObjects 是文件夹中的对象,ObjectListing.getCommonPrefixes 是文件夹中的子文件夹。

5. 删除对象

删除单个对象

通过 WosClient.deleteObject 删除单个对象,以下代码展示如何删除单个对象::

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);
wosClient.deleteObject("bucketname", "objectname");

批量删除对象

通过 WosClient.deleteObjects 批量删除对象(每次最多1000个对象),以下代码展示了如何进行批量删除空间内所有对象:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";
WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

DeleteObjectsRequest deleteRequest = new DeleteObjectsRequest("bucketname");
wosClient.deleteObjects(deleteRequest);

6. 复制对象

复制对象即为 WOS 上已存在对象创建副本。

您可以通过 WosClient.copyObject 复制对象,并可重新指定新对象属性和权限,支持条件复制。

操作限制

  • 用户需有待复制源对象读权限。
  • 不支持跨区域复制。
  • 源对象大小不得超过5GB(小于1GB建议简单复制,大于1GB建议分段复制)。
  • 存储类型为归档类型时需先进行取回。

简单复制

以下代码展示了如何进行简单复制:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

try{
    CopyObjectResult result = wosClient.copyObject("sourcebucketname", "sourceobjectname", "destbucketname", "destobjectname");
    System.out.println("\t" + result.getStatusCode());
    System.out.println("\t" + result.getEtag());
}
catch (WosException e)
{
    // 复制失败
    System.out.println("HTTP Code: " + e.getResponseCode());
    System.out.println("Error Code:" + e.getErrorCode());
    System.out.println("Error Message: " + e.getErrorMessage());
    System.out.println("Request ID:" + e.getErrorRequestId());
    System.out.println("Host ID:" + e.getErrorHostId());
}

重写对象属性

以下代码展示了如何在复制对象时重写对象属性:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

CopyObjectRequest request = new CopyObjectRequest("sourcebucketname", "sourceobjectname", "destbucketname", "destobjectname");
// 设置进行对象属性重写
request.setReplaceMetadata(true);
ObjectMetadata newObjectMetadata = new ObjectMetadata();
newObjectMetadata.setContentType("image/jpeg");
newObjectMetadata.addUserMetadata("property", "property-value");
newObjectMetadata.setObjectStorageClass(StorageClassEnum.WARM);
request.setNewObjectMetadata(newObjectMetadata);
CopyObjectResult result = wosClient.copyObject(request);
System.out.println("\t" + result.getEtag());

说明:

  • CopyObjectRequest.setReplaceMetadata 需配合 .setNewObjectMetadata 使用。

限定条件复制

复制对象时,可以指定一个或多个限定条件,满足限定条件时则进行复制,否则抛出异常,复制对象失败。

您可以使用的限定条件如下:

参数 作用说明 WOS Java SDK对应方法
Copy-Source-If-Modified-Since 若源对象修改时间晚于该参数值指定的时间,则进行复制,否则抛出异常。 CopyObjectRequest.setIfModifiedSince
Copy-Source-If-Unmodified-Since 若源对象修改时间早于该参数值指定的时间,则进行复制,否则抛出异常。 CopyObjectRequest.setIfUnmodifiedSince
Copy-Source-If-Match 若源对象 ETag 与该参数值相同,则进行复制,否则抛出异常。 CopyObjectRequest.setIfMatchTag
Copy-Source-If-None-Match 若源对象 ETag 与该参数值相同,则进行复制,否则抛出异常。 CopyObjectRequest.setIfNoneMatchTag

说明:

  • 源对象ETag为对象MD5值。
  • 若限定条件不符则 HTTP 状态码为 412 precondition failed。
  • Copy-Source-If-Modified-Since 和 Copy-Source-If-None-Match 可一起用;Copy-Source-If-Unmodified-Since 和 Copy-Source-If-Match 可一起用。

示例代码

以下代码展示了如何进行限定条件复制:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

// 创建WosClient实例
WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

CopyObjectRequest request = new CopyObjectRequest("sourcebucketname", "sourceobjectname", "destbucketname", "destobjectname");

request.setIfModifiedSince(new SimpleDateFormat("yyyy-MM-dd").parse("2016-01-01"));
request.setIfNoneMatchTag("none-match-etag");

CopyObjectResult result = wosClient.copyObject(request);
System.out.println("\t" + result.getEtag());

分段复制

分段复制是分段上传的一种特殊情况,即上传任务中的段通过复制已有对象(或部分)来实现。
可通过 WosClient.copyPart 实现分段复制。您可以通过WosClient.copyPart来复制段。以下代码展示了如何使用分段复制模式复制大对象:

String endPoint = "https://your-endpoint";
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";

final String destBucketName = "destbucketname";
final String destObjectKey = "destobjectname";
final String sourceBucketName = "sourcebucketname";
final String sourceObjectKey = "sourceobjectname";
// 创建WosClient实例
final WosClient wosClient = new WosClient(ak, sk, endPoint, regionName);

// 初始化线程池
ExecutorService executorService = Executors.newFixedThreadPool(20);

// 初始化分段上传任务
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(destBucketName, destObjectKey);
InitiateMultipartUploadResult result = wosClient.initiateMultipartUpload(request);

final String uploadId = result.getUploadId();
System.out.println("\t"+ uploadId + "\n");

// 获取大对象信息
ObjectMetadata metadata = wosClient.getObjectMetadata(sourceBucketName, sourceObjectKey);
// 每段复制100MB
long partSize = 100 * 1024 * 1024L;
long objectSize = metadata.getContentLength();

// 计算需要复制的段数
long partCount = objectSize % partSize == 0 ? objectSize / partSize : objectSize / partSize + 1;

final List<PartEtag> partEtags = Collections.synchronizedList(new ArrayList<PartEtag>());

// 执行并发复制段
for (int i = 0; i < partCount; i++)
{
    // 复制段起始位置
    final long rangeStart = i * partSize;
    // 复制段结束位置
    final long rangeEnd = (i + 1 == partCount) ? objectSize - 1 : rangeStart + partSize - 1;
    // 分段号
    final int partNumber = i + 1;
    executorService.execute(new Runnable()
    {
        @Override
        public void run()
        {
            CopyPartRequest request = new CopyPartRequest();
            request.setUploadId(uploadId);
            request.setSourceBucketName(sourceBucketName);
            request.setSourceObjectKey(sourceObjectKey);
            request.setDestinationBucketName(destBucketName);
            request.setDestinationObjectKey(destObjectKey);
            request.setByteRangeStart(rangeStart);
            request.setByteRangeEnd(rangeEnd);
            request.setPartNumber(partNumber);
            CopyPartResult result;
            try
            {
                result = wosClient.copyPart(request);
                System.out.println("Part#" + partNumber + " done\n");
                partEtags.add(new PartEtag(result.getEtag(), result.getPartNumber()));
            }
            catch (WosException e)
            {
                e.printStackTrace();
            }
        }
    });
}

// 等待复制完成
executorService.shutdown();
while (!executorService.isTerminated())
{
    try
    {
        executorService.awaitTermination(5, TimeUnit.SECONDS);
    }
    catch (InterruptedException e)
    {
        e.printStackTrace();
    }
}

// 合并段
CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(destBucketName, destObjectKey, uploadId, partEtags);
wosClient.completeMultipartUpload(completeMultipartUploadRequest);
本篇文档内容对您是否有帮助?
有帮助
我要反馈
提交成功!非常感谢您的反馈,我们会继续努力做到更好!