Copy files
Copy files
Copy a file
Users can copy an object using the bos_copy_object function, as shown in the following code:
1 bos_pool_t *p = NULL;
2 int is_cname = 0;
3 bos_status_t *s = NULL;
4 bos_request_options_t *options = NULL;
5 bos_string_t bucket;
6 bos_string_t object;
7 bos_string_t src_bucket;
8 bos_string_t src_object;
9 bos_string_t src_endpoint;
10 bos_table_t *resp_headers = NULL;
11 bos_pool_create(&p, NULL);
12 options = bos_request_options_create(p);
13 init_test_request_options(options, is_cname);
14 bos_str_set(&bucket, TEST_BUCKET_NAME);
15 bos_str_set(&object, "test_copy.txt");
16 bos_str_set(&src_bucket, TEST_BUCKET_NAME);
17 bos_str_set(&src_object, "bos_test_put_object.ts");
18 bos_str_set(&src_endpoint, options->config->endpoint.data);
19 bos_copy_object_params_t *params = NULL;
20 params = bos_create_copy_object_params(p);
21 bos_table_t *headers = bos_table_make(p, 2);
22 apr_table_add(headers, "x-bce-metadata-directive", "replace");
23 apr_table_add(headers, "x-bce-storage-class", "STANDARD_IA");
24 json_t *root;
25 s = bos_copy_object(options, &src_bucket, &src_object, &bucket, &object, headers, &root, &resp_headers);
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:
1void test_upload_part_copy(CuTest *tc)
2{
3 bos_pool_t *p = NULL;
4 bos_request_options_t *options = NULL;
5 int is_cname = 0;
6 bos_string_t upload_id;
7 bos_list_upload_part_params_t *list_upload_part_params = NULL;
8 bos_upload_part_copy_params_t *upload_part_copy_params1 = NULL;
9 bos_upload_part_copy_params_t *upload_part_copy_params2 = NULL;
10 bos_table_t *headers = NULL;
11 bos_table_t *query_params = NULL;
12 bos_table_t *resp_headers = NULL;
13 bos_table_t *list_part_resp_headers = NULL;
14 bos_list_t complete_part_list;
15 bos_list_part_content_t *part_content = NULL;
16 bos_complete_part_content_t *complete_content = NULL;
17 bos_table_t *complete_resp_headers = NULL;
18 bos_status_t *s = NULL;
19 int part1 = 1;
20 int part2 = 2;
21 char *local_filename = "test_upload_part_copy.file";
22 char *download_filename = "test_upload_part_copy.file.download";
23 char *source_object_name = "bos_test_upload_part_copy_source_object";
24 char *dest_object_name = "bos_test_upload_part_copy_dest_object";
25 FILE *fd = NULL;
26 bos_string_t download_file;
27 bos_string_t dest_bucket;
28 bos_string_t dest_object;
29 int64_t range_start1 = 0;
30 int64_t range_end1 = 6000000;
31 int64_t range_start2 = 6000001;
32 int64_t range_end2;
33 bos_string_t data;
34 bos_pool_create(&p, NULL);
35 options = bos_request_options_create(p);
36 // create multipart upload local file
37 make_rand_string(p, 10 * 1024 * 1024, &data);
38 fd = fopen(local_filename, "w");
39 CuAssertTrue(tc, fd != NULL);
40 fwrite(data.data, sizeof(data.data[0]), data.len, fd);
41 fclose(fd);
42 init_test_request_options(options, is_cname);
43 headers = bos_table_make(p, 0);
44 s = create_test_object_from_file(options, TEST_BUCKET_NAME, source_object_name,
45 local_filename, headers);
46 //init mulitipart
47 s = init_test_multipart_upload(options, TEST_BUCKET_NAME, dest_object_name, &upload_id);
48 //upload part copy 1
49 upload_part_copy_params1 = bos_create_upload_part_copy_params(p);
50 bos_str_set(&upload_part_copy_params1->copy_source, "mybucket.bcebos.com/bos_test_upload_part_copy_source_object");
51 bos_str_set(&upload_part_copy_params1->dest_bucket, TEST_BUCKET_NAME);
52 bos_str_set(&upload_part_copy_params1->dest_object, dest_object_name);
53 bos_str_set(&upload_part_copy_params1->upload_id, upload_id.data);
54 upload_part_copy_params1->part_num = part1;
55 upload_part_copy_params1->range_start = range_start1;
56 upload_part_copy_params1->range_end = range_end1;
57 headers = bos_table_make(p, 0);
58 s = bos_upload_part_copy(options, upload_part_copy_params1, headers, &resp_headers);
59 //upload part copy 2
60 resp_headers = NULL;
61 range_end2 = get_file_size(local_filename) - 1;
62 upload_part_copy_params2 = bos_create_upload_part_copy_params(p);
63 bos_str_set(&upload_part_copy_params2->copy_source, "mybucket.bcebos.com/bos_test_upload_part_copy_source_object");
64 bos_str_set(&upload_part_copy_params2->dest_bucket, TEST_BUCKET_NAME);
65 bos_str_set(&upload_part_copy_params2->dest_object, dest_object_name);
66 bos_str_set(&upload_part_copy_params2->upload_id, upload_id.data);
67 upload_part_copy_params2->part_num = part2;
68 upload_part_copy_params2->range_start = range_start2;
69 upload_part_copy_params2->range_end = range_end2;
70 headers = bos_table_make(p, 0);
71 s = bos_upload_part_copy(options, upload_part_copy_params2, headers, &resp_headers);
72 //list part
73 list_upload_part_params = bos_create_list_upload_part_params(p);
74 list_upload_part_params->max_ret = 10;
75 bos_list_init(&complete_part_list);
76 bos_str_set(&dest_bucket, TEST_BUCKET_NAME);
77 bos_str_set(&dest_object, dest_object_name);
78 s = bos_list_upload_part(options, &dest_bucket, &dest_object, &upload_id,
79 list_upload_part_params, &list_part_resp_headers);
80 bos_list_for_each_entry(bos_list_part_content_t, part_content, &list_upload_part_params->part_list, node) {
81 complete_content = bos_create_complete_part_content(p);
82 bos_str_set(&complete_content->part_number, part_content->part_number.data);
83 bos_str_set(&complete_content->etag, part_content->etag.data);
84 bos_list_add_tail(&complete_content->node, &complete_part_list);
85 }
86 s = bos_complete_multipart_upload(options, &dest_bucket, &dest_object,
87 &upload_id, &complete_part_list, headers, &complete_resp_headers);
88 //check upload copy part content equal to local file
89 headers = bos_table_make(p, 0);
90 bos_str_set(&download_file, download_filename);
91 s = bos_get_object_to_file(options, &dest_bucket, &dest_object, headers,
92 query_params, &download_file, &resp_headers);
93 remove(download_filename);
94 remove(local_filename);
95 bos_pool_destroy(p);
96 printf("test_upload_part_copy ok\n");
97}
Use the automatic switching function
1void test_upload_file(CuTest *tc)
2{
3 bos_pool_t *p = NULL;
4 bos_string_t bucket;
5 char *object_name = "bos_test_multipart_upload_from_file";
6 bos_string_t object;
7 int is_cname = 0;
8 bos_request_options_t *options = NULL;
9 bos_status_t *s = NULL;
10 int part_size = 100 * 1024;
11 bos_string_t upload_id;
12 bos_string_t filepath;
13 bos_pool_create(&p, NULL);
14 options = bos_request_options_create(p);
15 init_test_request_options(options, is_cname);
16 bos_str_set(&bucket, TEST_BUCKET_NAME);
17 bos_str_set(&object, object_name);
18 bos_str_null(&upload_id);
19 bos_str_set(&filepath, __FILE__);
20 s = bos_upload_file(options, &bucket, &object, &upload_id, &filepath,
21 part_size, NULL);
22 bos_pool_destroy(p);
23 printf("test_upload_file ok\n");
24}
