You can copy an object from a source Object Storage Service (OSS) on CloudBox bucket to a destination OSS on CloudBox bucket that is located in the same region without modifying the content of the object.
Limits
Objects cannot be copied between OSS on CloudBox buckets located in different regions. For example, you cannot copy objects from OSS on CloudBox buckets in the China (Hangzhou) region to OSS on CloudBox buckets in the China (Shanghai) region.
Appendable objects cannot be copied.
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, when you copy an object that has the same name as an existing object in the destination OSS on CloudBox bucket, the copied object overwrites the existing object in the destination OSS on CloudBox bucket. You can use one of the following methods to prevent your objects from being unexpectedly overwritten:
Enable versioning for the destination OSS on CloudBox bucket
If versioning is enabled for the destination OSS on CloudBox bucket, deleted and overwritten objects in the destination OSS on CloudBox bucket are saved as previous versions. You can restore previous versions of an object at any time.
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
OSS on CloudBox allows you to copy an object less than 1 GB in size by calling the CopyObject operation.
Use OSS SDK for Java
You can copy an object by using only OSS SDK for Java. The version of OSS SDK for Java must be 3.15.0 or later. The following sample code provides an example on how to call the CopyObject operation to copy an object less than 1 GB in size by using OSS SDKs for Java:
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 the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Specify the region in which the source and destination OSS on CloudBox buckets are located.
String region = "cn-hangzhou";
// Specify the ID of the cloud box.
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. Do not include the bucket name in the full path of the object.
String sourceKey = "srcexampleobject.txt";
// Specify the name of the destination OSS on CloudBox bucket that is located in the same region as the source OSS on CloudBox bucket.
String destinationBucketName = "desexamplebucket";
// Specify the full path of the destination object. Do not include the bucket name in the full path.
String destinationKey = "desexampleobject.txt";
// Create an OSSClient instance.
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);
// Specify new object metadata.
ObjectMetadata meta = new ObjectMetadata();
meta.setContentType("text/txt");
// Specify whether the CopyObject operation overwrites an existing object that has the same name. In this example, this parameter is set to true, which specifies that the uploaded object that has the same name as the existing object does not overwrite the existing object.
// meta.setHeader("x-oss-forbid-overwrite", "true");
// Specify the path of the source object.
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE, "/examplebucket/recode-test.txt");
// If the ETag value of the source object is the same as the ETag value that is specified in the request, OSS copies the object and returns 200 OK.
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
// If the ETag value of the source object is different from the ETag value that is specified in the request, OSS copies the object and returns 200 OK.
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_NONE_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
// If the time specified in the request is the same as or later than the modified time of the object, OSS copies the object and returns 200 OK.
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_UNMODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
// If the source object is modified after the time specified in the request, OSS copies the object.
// meta.setHeader(OSSHeaders.COPY_OBJECT_SOURCE_IF_MODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
// Specify the method that is used to configure the metadata of the destination object. In this example, the method is set to COPY, which specifies that the metadata of the source object is copied to the destination object.
// meta.setHeader(OSSHeaders.COPY_OBJECT_METADATA_DIRECTIVE, "COPY");
// Specify the server-side encryption algorithm that is used to encrypt the destination object when the object is created.
// meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION, ObjectMetadata.KMS_SERVER_SIDE_ENCRYPTION);
// Specify the customer master key (CMK) that is managed by Key Management Service (KMS). This parameter takes effect only if you set x-oss-server-side-encryption to KMS.
// meta.setHeader(OSSHeaders.OSS_SERVER_SIDE_ENCRYPTION_KEY_ID, "9468da86-3509-4f8d-a61e-6eab1eac****");
// Specify the access control list (ACL) of the destination object. In this example, the ACL is set to private, which specifies that only the object owner and authorized users have the read and write permissions on the object.
// meta.setHeader(OSSHeaders.OSS_OBJECT_ACL, CannedAccessControlList.Private);
// Specify the storage class of the destination object. In this example, the storage class is set to Standard.
// meta.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard);
// Specify one or more tags for the destination object.
// meta.setHeader(OSSHeaders.OSS_TAGGING, "a:1");
// Specify the method that is used to configure tags for the destination object. In this example, the method is set to COPY, which specifies that the tags of the source object are copied to the destination object.
// meta.setHeader(OSSHeaders.COPY_OBJECT_TAGGING_DIRECTIVE, "COPY");
copyObjectRequest.setNewObjectMetadata(meta);
// Copy the object.
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
You can use ossutil to copy an object less than 1 GB in size. For more information, see Copy objects.
Use ossutil
You can use ossutil to copy an object larger than 1 GB in size. For more information, see Copy objects.
Copy a large object
OSS on CloudBox allows you to copy an object greater than 1 GB in size by calling the UploadPartCopy operation.
Use OSS SDK for Java
You can copy an object by using only OSS SDK for Java. The version of OSS SDK for Java must be 3.15.0 or later. The following sample code provides an example on how to call the UploadPartCopy operation to copy an object greater than 1 GB in size by using OSS SDKs for Java:
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 the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Specify the region in which the source and destination OSS on CloudBox buckets are located.
String region = "cn-hangzhou";
// Specify the ID of the cloud box.
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. Do not include the bucket name in the full path of the object.
String sourceKey = "srcexampleobject.txt";
// Specify the name of the destination OSS on CloudBox bucket that is located in the same region as the source OSS on CloudBox bucket.
String destinationBucketName = "desexamplebucket";
// Specify the full path of the destination object. Do not include the bucket name in the full path of the object.
String destinationKey = "desexampleobject.txt";
// Create an OSSClient instance.
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);
// Query the size of the source object.
long contentLength = objectMetadata.getContentLength();
// Set the size of each part to 10 MB. Unit: bytes.
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);
// Initiate a multipart copy task. Specify the metadata of the destination object by using InitiateMultipartUploadRequest.
InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(destinationBucketName, destinationKey);
InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest);
String uploadId = initiateMultipartUploadResult.getUploadId();
// Start the multipart copy task.
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 by using UploadPartCopyRequest.
UploadPartCopyRequest uploadPartCopyRequest =
new UploadPartCopyRequest(sourceBucketName, sourceKey, destinationBucketName, destinationKey);
uploadPartCopyRequest.setUploadId(uploadId);
uploadPartCopyRequest.setPartSize(size);
uploadPartCopyRequest.setBeginIndex(skipBytes);
uploadPartCopyRequest.setPartNumber(i + 1);
//Map headers = new HashMap();
// Specify the path of the source object.
// headers.put(OSSHeaders.COPY_OBJECT_SOURCE, "/examplebucket/desexampleobject.txt");
// Specify the range of data that you want to copy. For example, if you set bytes to 0-1023, the first 1,024 bytes of the source object are copied.
// headers.put(OSSHeaders.COPY_SOURCE_RANGE, "bytes=0~1023");
// If the ETag value of the source object is the same as the ETag value that is specified in the request, OSS copies the object and returns 200 OK.
// headers.put(OSSHeaders.COPY_OBJECT_SOURCE_IF_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
// If the ETag value of the source object is different from the ETag value that is specified in the request, OSS copies the object and returns 200 OK.
// headers.put(OSSHeaders.COPY_OBJECT_SOURCE_IF_NONE_MATCH, "5B3C1A2E053D763E1B002CC607C5****");
// If the time specified in the request is the same as or later than the modified time of the object, OSS copies the object and returns 200 OK.
// headers.put(OSSHeaders.COPY_OBJECT_SOURCE_IF_UNMODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
// If the source object is modified after the time that is specified in the request, OSS copies the object.
// headers.put(OSSHeaders.COPY_OBJECT_SOURCE_IF_MODIFIED_SINCE, "2021-12-09T07:01:56.000Z");
// uploadPartCopyRequest.setHeaders(headers);
UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest);
// Store the returned PartETags in 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
You can use ossutil to copy an object larger than 1 GB in size. For more information, see Copy objects.
Use the OSS API
If your business requires a high level of customization, you can directly call the OSS API. To directly call an API operation, you must include the signature calculation in your code. For more information, see UploadPartCopy.