Copy files
Copy files
Copy a file
Users can copy an object using the copy_object function, as shown in the following code:
1void copyObject(Client& client, std::string destBucketName, std::string destKey, const std::string& srcBucketName, const std::string& srcKey) {
2
3 // Copy Object
4 int ret = client.copy_object(srcBucketName, srcKey, destBucketName, destKey, "STANDARD");//The target object is standard storage
5}
The CopyObjectResponse object contains the ETag and modification time of the new object.
Users can also copy object via CopyObjectRequest. the code is as follows:
1// Initialize a client
2Client client = ...;
3
4 // Create CopyObjectRequest object
5CopyObjectRequest copyObjectRequest(destBucketName, destKey, srcBucketName, srcKey);
6
7 // Set Metadata
8ObjectMetaData* userMetadata = copyObjectRequest.mutable_meta();
9userMetadata->set_user_meta("userMetaKey", "userMetaValue");
10
11 // Copy Object
12CopyObjectResponse copyObjectResponse;
13int ret = client.copy_object(copyObjectRequest, ©ObjectResponse);
14
15std::cout << "ETag: " + copyObjectResponse.etag() <<
16 " LastModified: " << copyObjectResponse.last_modified());
Synchronous copy function
Currently, BOS’s CopyObject API operates in a synchronous manner. This means BOS waits until the copy operation is fully completed before returning a success status. While synchronous copying provides a more accurate status for users, it also takes longer and is proportional to the file size.
The synchronous copy approach aligns better with industry standards and improves compatibility with other platforms. It also simplifies the server’s business logic and enhances service efficiency.
Multipart copy
Apart from using the CopyObject API for copying, BOS offers another method—Multipart Upload Copy. This method is suitable for the following application scenarios (but not limited to these):
- When a resumable copy process is required.
- For copying files larger than 5GB.
- When the connection to the BOS server frequently disconnects due to poor network conditions.
The following section introduces the step-by-step process for implementing the three-step copy method.
The three-step copy process includes three stages: initialization ("init"), "copy part," and completion. The initialization and completion steps are the same as those for multipart uploads.
For easier understanding, the complete code for three-step copy is provided below:
1//Step I: init
2InitMultiUploadRequest initMultiUploadRequest("targetBucketName","targetObjectName");
3InitMultiUploadResponse initMultiUploadResponse;
4client.init_multipart_upload(initMultiUploadRequest, &initMultiUploadResponse);
5 //Get object size
6HeadObjectRequest request("targetBucketName", "targetObjectName");
7HeadObjectResponse response;
8client.head_object(request, &response);
9if (response.is_fail()) {
10 return RET_SERVICE_ERROR;
11}
12long left_size = response.meta().content_length();
13 //Step II: Multipart copy
14long skipBytes = 0;
15int partNumber = 1;
16std::vector<part_t> partETags;
17while (left_size > 0) {
18 long partSize = 1024 * 1024 * 5L;
19 if (left_size < partSize) {
20 partSize = left_size;
21 }
22 CopyPartRequest copyPartRequest;
23 copyPartRequest.set_upload_id(initMultiUploadResponse.upload_id());
24 copyPartRequest.set_bucket_name("targetBucketName");
25 copyPartRequest.set_object_name("targetObjectName");
26 copyPartRequest.set_source_bucket_name("sourceBucketName");
27 copyPartRequest.set_source_object_name("sourceObjectName");
28 copyPartRequest.set_range(skipBytes, skipBytes + partSize - 1);
29 copyPartRequest.set_part_number(partNumber);
30 CopyPartResponse copyPartResponse;
31 client.copy_part(copyPartRequest, ©PartResponse);
32 //Save the returned partNumber and ETag to the vector
33 part_t partInfo;
34 partInfo.etag = copyPartResponse.etag();
35 partInfo.part_number = partNumber;
36 partETags.push_back(partInfo);
37 left_size -= partSize;
38 skipBytes += partSize;
39 partNumber+=1;
40}
41 //Step III: complete
42CompleteMultipartUploadRequest completeMultipartUploadRequest("targetBucketName", "targetObjectName", initMultiUploadResponse.upload_id());
43 //Add part information, i.e., the order of part merging
44for (part_t partInfo : partEtags) {
45 completeMultipartUploadRequest.add_part(partInfo.part_number, partInfo.etag);
46}
47
48 // Complete multipart upload
49CompleteMultipartUploadResponse completeMultipartUploadResponse;
50int ret = client.complete_multipart_upload(completeMultipartUploadRequest, &completeMultipartUploadResponse);
51
52 // Print Object's ETag
53std::cout << completeMultipartUploadResponse.etag() << std::endl;
Note:
- The offset parameter is specified in bytes and represents the starting position of the part within the file.
- The size parameter is in bytes and defines the size of each part. Except for the last part, the size of other Parts must be larger than 5MB。
Using convenience APIs
parallel_copy uses a concurrent API to improve request throughput and implement multipart copy
1client.parallel_copy(srcBucketName, sourceObjectName, destBucketName, destObjectName);
