All Products
Search
Document Center

Object Storage Service:Copy objects in CloudBox

Last Updated:Aug 08, 2025

You can copy an object from a source OSS on CloudBox bucket to a destination OSS on CloudBox bucket in the same region without changing the object content. This process supports use cases such as data backup, distribution, and disaster recovery. It improves data availability and redundancy, and ensures data consistency and security between buckets. The destination bucket must be in the same region as the source bucket. CloudBox is an efficient and reliable data storage and management service from Alibaba Cloud.

Limits

You cannot copy objects across regions. For example, you cannot copy an object from a bucket in the China (Hangzhou) region to a bucket in the China (Shanghai) region.

Usage notes

  • You must have read permissions on the source object and read and write permissions on the destination bucket. Otherwise, the copy operation fails.

  • By default, copying an object overwrites an existing object with the same name in the destination bucket. To prevent objects from being accidentally overwritten, you can use one of the following methods:

    • Enable versioning

      Overwritten or deleted objects are saved as historical versions. You can restore them at any time. For more information, see Versioning for CloudBox.

    • Include the x-oss-forbid-overwrite header in the copy request

      You can include the x-oss-forbid-overwrite header in the copy request and set the header to true to disable object overwriting. If you copy an object that has the same name as an existing object in the destination bucket, the object fails to be copied and the FileAlreadyExists error code is returned.

Copy a small object

You can copy objects smaller than 1 GB in OSS on CloudBox by calling the CopyObject API operation.

Use OSS SDK for Java

You can copy objects only using Object Storage Service (OSS) SDK for Java 3.15.0 or later.

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;

public class Demo {
    public static void main(String[] args) throws Exception {
        // Specify the data endpoint of the OSS on CloudBox bucket.
        String endpoint = "https://cb-f8z7yvzgwfkl9q0h****.cn-hangzhou.oss-cloudbox.aliyuncs.com";
        // Obtain access credentials from environment variables. Before you run this sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set.
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Specify the region where the source and destination OSS on CloudBox buckets are located.
        String region = "cn-hangzhou";
        // Specify the ID of the CloudBox.
        String cloudBoxId = "cb-f8z7yvzgwfkl9q0h****";
        // Specify the name of the source OSS on CloudBox bucket.
        String sourceBucketName = "srcexamplebucket";
        // Specify the full path of the source object. The full path cannot include the bucket name.
        String sourceKey = "srcexampleobject.txt";
        // Specify the name of the destination OSS on CloudBox bucket that is in the same region as the source bucket.
        String destinationBucketName = "desexamplebucket";
        // Specify the full path of the destination object. The full path cannot include the bucket name.
        String destinationKey = "desexampleobject.txt";

        // Create an OSSClient instance.
        // When the OSSClient instance is no longer used, call the shutdown method to release its resources.
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
        conf.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(new DefaultCredentialProvider(credentialsProvider.getCredentials()))
                .clientConfiguration(conf)
                .region(region)
                .cloudBoxId(cloudBoxId)
                .build();

        try {
            // Create a CopyObjectRequest object.
            CopyObjectRequest copyObjectRequest = new CopyObjectRequest(sourceBucketName, sourceKey, destinationBucketName, destinationKey);

            // Set new object metadata.
            ObjectMetadata meta = new ObjectMetadata();
            meta.setContentType("text/txt");
            // Specify whether to overwrite the destination object if it has the same name. In this example, this parameter is set to true to prohibit overwriting.
            // meta.setHeader("x-oss-forbid-overwrite", "true");
            // Specify the source path for the copy operation.
            // meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE, "/examplebucket/recode-test.txt");
            // If the ETag of the source object matches the ETag you provide, the copy operation is performed and 200 OK is returned.
            // meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
            // If the ETag of the source object does not match the ETag you provide, the copy operation is performed and 200 OK is returned.
            // meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_NONE_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
            // If the specified time is the same as or later than the actual modification time of the object, the object is copied and 200 OK is returned.
            // meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_UNMODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
            // If the source object was modified after the specified time, the copy operation is performed.
            // meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
            // Specify how to set the metadata of the destination object. In this example, this parameter is set to COPY to copy the metadata from the source object to the destination object.
            // meta.setHeader(OSSHeaders.COPY_OBJECT_METADATA_DIRECTIVE, "COPY");
            // Specify the server-side encryption algorithm for OSS to use when creating the destination object.
            // meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION, ObjectMetadata.KMS_SERVER_SIDE_ENCRYPTION);
            // Specify the customer master key (CMK) managed by KMS. This parameter is valid only when x-oss-server-side-encryption is set to KMS.
            // meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION_KEY_ID, "9468da86-3509-4f8d-a61e-6eab1eac****");
            // Specify the access permissions for the destination object when it is created in OSS. In this example, this parameter is set to Private. This means only the object owner and authorized users have read and write permissions on the object. Other users cannot access the object.
            // meta.setHeader(OSSHeaders.OSS_OBJECT_ACL, CannedAccessControlList.Private);
            // Specify the storage class of the object. In this example, this parameter is set to Standard.
            // meta.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard);
            // Specify object tags. You can specify multiple tags at the same time.
            // meta.setHeader(OSSHeaders.OSS_TAGGING, "a:1");
            // Specify how to set tags for the destination object. In this example, this parameter is set to COPY to copy the tags from the source object to the destination object.
            // meta.setHeader(OSSHeaders.COPY_OBJECT_TAGGING_DIRECTIVE, "COPY");
            copyObjectRequest.setNewObjectMetadata(meta);

            // Copy the file.
            CopyObjectResult result = ossClient.copyObject(copyObjectRequest);
            System.out.println("ETag: " + result.getETag() + " LastModified: " + result.getLastModified());
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

Use ossutil

For more information about using ossutil to copy small objects, see cp (Copy files).

Copy a large object

You can copy objects larger than 1 GB in OSS on CloudBox by calling the UploadPartCopy API operation.

Use OSS SDK for Java

You can copy objects only using OSS SDK for Java 3.15.0 or later.

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import java.util.ArrayList;
import java.util.List;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;

public class Demo {
    public static void main(String[] args) throws Exception {
        // Specify the data endpoint of the OSS on CloudBox bucket.
        String endpoint = "https://cb-f8z7yvzgwfkl9q0h****.cn-hangzhou.oss-cloudbox.aliyuncs.com";
        // Obtain access credentials from environment variables. Before you run this sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set.
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Specify the region where the source and destination OSS on CloudBox buckets are located.
        String region = "cn-hangzhou";
        // Specify the ID of the CloudBox.
        String cloudBoxId = "cb-f8z7yvzgwfkl9q0h****";
        // Specify the name of the source OSS on CloudBox bucket.
        String sourceBucketName = "srcexamplebucket";
        // Specify the full path of the source object. The full path cannot include the bucket name.
        String sourceKey = "srcexampleobject.txt";
        // Specify the name of the destination OSS on CloudBox bucket that is in the same region as the source bucket.
        String destinationBucketName = "desexamplebucket";
        // Specify the full path of the destination object. The full path cannot include the bucket name.
        String destinationKey = "desexampleobject.txt";

        // Create an OSSClient instance.
        // When the OSSClient instance is no longer used, call the shutdown method to release its resources.
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
        conf.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(new DefaultCredentialProvider(credentialsProvider.getCredentials()))
                .clientConfiguration(conf)
                .region(region)
                .cloudBoxId(cloudBoxId)
                .build();

        try {
            ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceKey);
            // Obtain the size of the file to be copied.
            long contentLength = objectMetadata.getContentLength();

            // Set the part size to 10 MB. The unit is byte.
            long partSize = 1024 * 1024 * 10;

            // Calculate the total number of parts.
            int partCount = (int) (contentLength / partSize);
            if (contentLength % partSize != 0) {
                partCount++;
            }
            System.out.println("total part count:" + partCount);

            // Initialize the copy task. You can specify the metadata of the destination object using InitiateMultipartUploadRequest.
            InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(destinationBucketName, destinationKey);
            InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest);
            String uploadId = initiateMultipartUploadResult.getUploadId();

            // Copy parts.
            List<PartETag> partETags = new ArrayList<PartETag>();
            for (int i = 0; i < partCount; i++) {
                // Calculate the size of each part.
                long skipBytes = partSize * i;
                long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes;

                // Create an UploadPartCopyRequest object. You can specify conditions using UploadPartCopyRequest.
                UploadPartCopyRequest uploadPartCopyRequest =
                        new UploadPartCopyRequest(sourceBucketName, sourceKey, destinationBucketName, destinationKey);
                uploadPartCopyRequest.setUploadId(uploadId);
                uploadPartCopyRequest.setPartSize(size);
                uploadPartCopyRequest.setBeginIndex(skipBytes);
                uploadPartCopyRequest.setPartNumber(i + 1);
                UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest);

                // Save the returned part ETags to partETags.
                partETags.add(uploadPartCopyResult.getPartETag());
            }

            // Complete the multipart copy task.
            CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(
                    destinationBucketName, destinationKey, uploadId, partETags);
            ossClient.completeMultipartUpload(completeMultipartUploadRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}     

Use ossutil

For more information about using ossutil to copy large objects, see cp (Copy files).

Use the REST API

If your program requires significant customization, you can make REST API requests directly. To make REST API requests, you must manually write code to calculate signatures. For more information, see UploadPartCopy.