拷贝文件
更新时间:2024-06-18
拷贝文件
拷贝一个文件
用户可以通过bos_copy_object函数拷贝一个Object,如下代码所示:
C
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
12 bos_pool_create(&p, NULL);
13 options = bos_request_options_create(p);
14 init_test_request_options(options, is_cname);
15 bos_str_set(&bucket, TEST_BUCKET_NAME);
16 bos_str_set(&object, "test_copy.txt");
17 bos_str_set(&src_bucket, TEST_BUCKET_NAME);
18 bos_str_set(&src_object, "bos_test_put_object.ts");
19 bos_str_set(&src_endpoint, options->config->endpoint.data);
20
21 bos_copy_object_params_t *params = NULL;
22 params = bos_create_copy_object_params(p);
23 bos_table_t *headers = bos_table_make(p, 2);
24 apr_table_add(headers, "x-bce-metadata-directive", "replace");
25 apr_table_add(headers, "x-bce-storage-class", "STANDARD_IA");
26 json_t *root;
27 s = bos_copy_object(options, &src_bucket, &src_object, &bucket, &object, headers, &root, &resp_headers);
同步Copy功能
当前BOS的CopyObject接口是通过同步方式实现的。同步方式下,BOS端会等待Copy实际完成才返回成功。同步Copy能帮助用户更准确的判断Copy状态,但用户感知的复制时间会变长,且复制时间和文件大小成正比。
同步Copy方式更符合业界常规,提升了与其它平台的兼容性。同步Copy方式还简化了BOS服务端的业务逻辑,提高了服务效率。
分块拷贝
除了通过CopyObject接⼝拷贝文件以外,BOS还提供了另外一种拷贝模式——Multipart Upload Copy。用户可以在如下的应用场景内(但不仅限于此),使用Multipart Upload Copy,如:
- 需要支持断点拷贝。
- 拷贝超过5GB大小的文件。
- 网络条件较差,和BOS的服务器之间的连接经常断开。
下面将介绍分步实现三步拷贝。
三步拷贝包含init、“拷贝分块”和complete三步,其中init和complete的操作同分块上传一致。
为了便于理解,下面提供三步拷贝完整代码:
C
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
35 bos_pool_create(&p, NULL);
36 options = bos_request_options_create(p);
37
38 // create multipart upload local file
39 make_rand_string(p, 10 * 1024 * 1024, &data);
40 fd = fopen(local_filename, "w");
41 CuAssertTrue(tc, fd != NULL);
42 fwrite(data.data, sizeof(data.data[0]), data.len, fd);
43 fclose(fd);
44
45 init_test_request_options(options, is_cname);
46 headers = bos_table_make(p, 0);
47 s = create_test_object_from_file(options, TEST_BUCKET_NAME, source_object_name,
48 local_filename, headers);
49 //init mulitipart
50 s = init_test_multipart_upload(options, TEST_BUCKET_NAME, dest_object_name, &upload_id);
51 //upload part copy 1
52 upload_part_copy_params1 = bos_create_upload_part_copy_params(p);
53 bos_str_set(&upload_part_copy_params1->copy_source, "mybucket.bcebos.com/bos_test_upload_part_copy_source_object");
54 bos_str_set(&upload_part_copy_params1->dest_bucket, TEST_BUCKET_NAME);
55 bos_str_set(&upload_part_copy_params1->dest_object, dest_object_name);
56 bos_str_set(&upload_part_copy_params1->upload_id, upload_id.data);
57 upload_part_copy_params1->part_num = part1;
58 upload_part_copy_params1->range_start = range_start1;
59 upload_part_copy_params1->range_end = range_end1;
60
61 headers = bos_table_make(p, 0);
62 s = bos_upload_part_copy(options, upload_part_copy_params1, headers, &resp_headers);
63 //upload part copy 2
64 resp_headers = NULL;
65 range_end2 = get_file_size(local_filename) - 1;
66 upload_part_copy_params2 = bos_create_upload_part_copy_params(p);
67 bos_str_set(&upload_part_copy_params2->copy_source, "mybucket.bcebos.com/bos_test_upload_part_copy_source_object");
68 bos_str_set(&upload_part_copy_params2->dest_bucket, TEST_BUCKET_NAME);
69 bos_str_set(&upload_part_copy_params2->dest_object, dest_object_name);
70 bos_str_set(&upload_part_copy_params2->upload_id, upload_id.data);
71 upload_part_copy_params2->part_num = part2;
72 upload_part_copy_params2->range_start = range_start2;
73 upload_part_copy_params2->range_end = range_end2;
74
75 headers = bos_table_make(p, 0);
76 s = bos_upload_part_copy(options, upload_part_copy_params2, headers, &resp_headers);
77 //list part
78 list_upload_part_params = bos_create_list_upload_part_params(p);
79 list_upload_part_params->max_ret = 10;
80 bos_list_init(&complete_part_list);
81
82 bos_str_set(&dest_bucket, TEST_BUCKET_NAME);
83 bos_str_set(&dest_object, dest_object_name);
84 s = bos_list_upload_part(options, &dest_bucket, &dest_object, &upload_id,
85 list_upload_part_params, &list_part_resp_headers);
86
87 bos_list_for_each_entry(bos_list_part_content_t, part_content, &list_upload_part_params->part_list, node) {
88 complete_content = bos_create_complete_part_content(p);
89 bos_str_set(&complete_content->part_number, part_content->part_number.data);
90 bos_str_set(&complete_content->etag, part_content->etag.data);
91 bos_list_add_tail(&complete_content->node, &complete_part_list);
92 }
93 s = bos_complete_multipart_upload(options, &dest_bucket, &dest_object,
94 &upload_id, &complete_part_list, headers, &complete_resp_headers);
95 //check upload copy part content equal to local file
96 headers = bos_table_make(p, 0);
97 bos_str_set(&download_file, download_filename);
98 s = bos_get_object_to_file(options, &dest_bucket, &dest_object, headers,
99 query_params, &download_file, &resp_headers);
100 remove(download_filename);
101 remove(local_filename);
102 bos_pool_destroy(p);
103
104 printf("test_upload_part_copy ok\n");
105}
使用自动切换函数
C
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
14 bos_pool_create(&p, NULL);
15 options = bos_request_options_create(p);
16 init_test_request_options(options, is_cname);
17 bos_str_set(&bucket, TEST_BUCKET_NAME);
18 bos_str_set(&object, object_name);
19 bos_str_null(&upload_id);
20 bos_str_set(&filepath, __FILE__);
21 s = bos_upload_file(options, &bucket, &object, &upload_id, &filepath,
22 part_size, NULL);
23 bos_pool_destroy(p);
24 printf("test_upload_file ok\n");
25}