Copy Object
Copy Object
Simply Copy Object
-
Basic workflow
- Create a BosClient instance.
- Execute the copyObject( ) method.
-
Example code
JavaScript1let options = { 2 'Content-Length': <file.size>, // Add http header 3 'Content-Type': 'application/json', // Add http header 4 'Cache-Control': 'public, max-age=31536000', // Specify cache directives 5 'Content-Disposition': 'attachment; filename="example.jpg"', // Indicate how the response content should be displayed 6 'x-bce-meta-foo1': 'bar1', // Overwrite custom meta information 7 'x-bce-meta-foo2': 'bar2', // Overwrite custom meta information 8 'x-bce-meta-foo3': 'bar3', // Overwrite custom meta information 9} 10 // SrcBucketName and SrcKey refer to the source bucket/object, and DestBucketName and DestKey refer to the destination bucket/object to which the copy is made 11client.copyObject(<SrcBucketName>, <SrcKey>, <DestBucketName>, <DestKey>, options);
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.
Set meta information for object
Meta information can be set by means of [copying bject](#Copy Object).
BOS modifies object metadata by copying the object. When copying, set the destination bucket and object as the source bucket and object, then apply the new metadata. If new metadata is not specified, an error will occur.
-
Example code
JavaScript1let options = {<meta_key>: <meta_value>} 2 // SrcBucketName and SrcKey refer to the source bucket/object 3 // DestBucketName = SrcBucketName, DestKey = SrcKey: the destination is the same as the original bucket/object 4client.copyObject(<SrcBucketName>, <SrcKey>, <DestBucketName>, <DestKey>, options);
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// Prepare
2let options = {
3 'Content-Length': <file.size>, // Add http header
4 'Content-Type': 'application/json', // Add http header
5 'Cache-Control': 'public, max-age=31536000', // Specify cache directives
6 'Content-Disposition': 'attachment; filename="example.jpg"', // Indicate how the response content should be displayed
7 'x-bce-meta-foo1': 'bar1', // Add custom meta information
8 'x-bce-meta-foo2': 'bar2', // Add custom meta information
9 'x-bce-meta-foo3': 'bar3', // Add custom meta information
10};
11 let PART_SIZE = 5 * 1024 * 1024; // Specify the part size
12 /** Step I: init **/
13 // SrcBucketName and SrcKey refer to the source bucket/object
14 // DestBucketName and DestKey refer to the destination bucket/dbject to which the copy is made
15client.initiateMultipartUpload(srcBucketName, SrcKey)
16 .then(function(response) {
17 uploadId = response.body.uploadId; // Get the server-generated uploadId to identify tasks
18 })
19
20 /**Step II: Multipart copy**/
21 // Get file size
22let leftSize = 0;
23client.getObjectMetadata(<SrcBucketName>, <SrcKey>).then(response => {
24 leftSize = response.http_headers?.['content-length']
25});
26let tasks = [];
27let offset = 0;
28let partNumber = 1;
29while (leftSize > 0) {
30 let partSize = Math.min(leftSize, PART_SIZE);
31 tasks.push({
32 file: <SrcKey>,
33 bucketName: <SrcBucketName>,
34 uploadId: uploadId,
35 partNumber: partNumber,
36 partSize: partSize,
37 start: offset,
38 stop: offset + partSize - 1
39 })
40 leftSize -= partSize;
41 offset += partSize;
42 partNumber+=1;
43}
44 let partList = [];
45 Promise.all(tasks.map(async (task, index) => {
46 return client.uploadPartCopy(<SrcBucketName>, <SrcKey>, <DestBucketName>, <DestKey>,uploadId, partNumber, range, <options>).then(response => {
47 // do something
48 })
49 })).then(response => {
50 partList = response
51 .map(res => ({partNumber: res.partNumber, eTag: res.http_headers.eTag}));
52 });
53 //Step III: Complete**/
54client.completeMultipartUpload(<DestBucketName>, <DestKey>, uploadId, partList)
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。
