拷贝文件
更新时间:2024-06-18
拷贝文件
拷贝一个文件
用户可以通过bos_copy_object函数拷贝一个Object,如下代码所示:
bos_pool_t *p = NULL;
int is_cname = 0;
bos_status_t *s = NULL;
bos_request_options_t *options = NULL;
bos_string_t bucket;
bos_string_t object;
bos_string_t src_bucket;
bos_string_t src_object;
bos_string_t src_endpoint;
bos_table_t *resp_headers = NULL;
bos_pool_create(&p, NULL);
options = bos_request_options_create(p);
init_test_request_options(options, is_cname);
bos_str_set(&bucket, TEST_BUCKET_NAME);
bos_str_set(&object, "test_copy.txt");
bos_str_set(&src_bucket, TEST_BUCKET_NAME);
bos_str_set(&src_object, "bos_test_put_object.ts");
bos_str_set(&src_endpoint, options->config->endpoint.data);
bos_copy_object_params_t *params = NULL;
params = bos_create_copy_object_params(p);
bos_table_t *headers = bos_table_make(p, 2);
apr_table_add(headers, "x-bce-metadata-directive", "replace");
apr_table_add(headers, "x-bce-storage-class", "STANDARD_IA");
json_t *root;
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的操作同分块上传一致。
为了便于理解,下面提供三步拷贝完整代码:
void test_upload_part_copy(CuTest *tc)
{
bos_pool_t *p = NULL;
bos_request_options_t *options = NULL;
int is_cname = 0;
bos_string_t upload_id;
bos_list_upload_part_params_t *list_upload_part_params = NULL;
bos_upload_part_copy_params_t *upload_part_copy_params1 = NULL;
bos_upload_part_copy_params_t *upload_part_copy_params2 = NULL;
bos_table_t *headers = NULL;
bos_table_t *query_params = NULL;
bos_table_t *resp_headers = NULL;
bos_table_t *list_part_resp_headers = NULL;
bos_list_t complete_part_list;
bos_list_part_content_t *part_content = NULL;
bos_complete_part_content_t *complete_content = NULL;
bos_table_t *complete_resp_headers = NULL;
bos_status_t *s = NULL;
int part1 = 1;
int part2 = 2;
char *local_filename = "test_upload_part_copy.file";
char *download_filename = "test_upload_part_copy.file.download";
char *source_object_name = "bos_test_upload_part_copy_source_object";
char *dest_object_name = "bos_test_upload_part_copy_dest_object";
FILE *fd = NULL;
bos_string_t download_file;
bos_string_t dest_bucket;
bos_string_t dest_object;
int64_t range_start1 = 0;
int64_t range_end1 = 6000000;
int64_t range_start2 = 6000001;
int64_t range_end2;
bos_string_t data;
bos_pool_create(&p, NULL);
options = bos_request_options_create(p);
// create multipart upload local file
make_rand_string(p, 10 * 1024 * 1024, &data);
fd = fopen(local_filename, "w");
CuAssertTrue(tc, fd != NULL);
fwrite(data.data, sizeof(data.data[0]), data.len, fd);
fclose(fd);
init_test_request_options(options, is_cname);
headers = bos_table_make(p, 0);
s = create_test_object_from_file(options, TEST_BUCKET_NAME, source_object_name,
local_filename, headers);
//init mulitipart
s = init_test_multipart_upload(options, TEST_BUCKET_NAME, dest_object_name, &upload_id);
//upload part copy 1
upload_part_copy_params1 = bos_create_upload_part_copy_params(p);
bos_str_set(&upload_part_copy_params1->copy_source, "mybucket.bcebos.com/bos_test_upload_part_copy_source_object");
bos_str_set(&upload_part_copy_params1->dest_bucket, TEST_BUCKET_NAME);
bos_str_set(&upload_part_copy_params1->dest_object, dest_object_name);
bos_str_set(&upload_part_copy_params1->upload_id, upload_id.data);
upload_part_copy_params1->part_num = part1;
upload_part_copy_params1->range_start = range_start1;
upload_part_copy_params1->range_end = range_end1;
headers = bos_table_make(p, 0);
s = bos_upload_part_copy(options, upload_part_copy_params1, headers, &resp_headers);
//upload part copy 2
resp_headers = NULL;
range_end2 = get_file_size(local_filename) - 1;
upload_part_copy_params2 = bos_create_upload_part_copy_params(p);
bos_str_set(&upload_part_copy_params2->copy_source, "mybucket.bcebos.com/bos_test_upload_part_copy_source_object");
bos_str_set(&upload_part_copy_params2->dest_bucket, TEST_BUCKET_NAME);
bos_str_set(&upload_part_copy_params2->dest_object, dest_object_name);
bos_str_set(&upload_part_copy_params2->upload_id, upload_id.data);
upload_part_copy_params2->part_num = part2;
upload_part_copy_params2->range_start = range_start2;
upload_part_copy_params2->range_end = range_end2;
headers = bos_table_make(p, 0);
s = bos_upload_part_copy(options, upload_part_copy_params2, headers, &resp_headers);
//list part
list_upload_part_params = bos_create_list_upload_part_params(p);
list_upload_part_params->max_ret = 10;
bos_list_init(&complete_part_list);
bos_str_set(&dest_bucket, TEST_BUCKET_NAME);
bos_str_set(&dest_object, dest_object_name);
s = bos_list_upload_part(options, &dest_bucket, &dest_object, &upload_id,
list_upload_part_params, &list_part_resp_headers);
bos_list_for_each_entry(bos_list_part_content_t, part_content, &list_upload_part_params->part_list, node) {
complete_content = bos_create_complete_part_content(p);
bos_str_set(&complete_content->part_number, part_content->part_number.data);
bos_str_set(&complete_content->etag, part_content->etag.data);
bos_list_add_tail(&complete_content->node, &complete_part_list);
}
s = bos_complete_multipart_upload(options, &dest_bucket, &dest_object,
&upload_id, &complete_part_list, headers, &complete_resp_headers);
//check upload copy part content equal to local file
headers = bos_table_make(p, 0);
bos_str_set(&download_file, download_filename);
s = bos_get_object_to_file(options, &dest_bucket, &dest_object, headers,
query_params, &download_file, &resp_headers);
remove(download_filename);
remove(local_filename);
bos_pool_destroy(p);
printf("test_upload_part_copy ok\n");
}
使用自动切换函数
void test_upload_file(CuTest *tc)
{
bos_pool_t *p = NULL;
bos_string_t bucket;
char *object_name = "bos_test_multipart_upload_from_file";
bos_string_t object;
int is_cname = 0;
bos_request_options_t *options = NULL;
bos_status_t *s = NULL;
int part_size = 100 * 1024;
bos_string_t upload_id;
bos_string_t filepath;
bos_pool_create(&p, NULL);
options = bos_request_options_create(p);
init_test_request_options(options, is_cname);
bos_str_set(&bucket, TEST_BUCKET_NAME);
bos_str_set(&object, object_name);
bos_str_null(&upload_id);
bos_str_set(&filepath, __FILE__);
s = bos_upload_file(options, &bucket, &object, &upload_id, &filepath,
part_size, NULL);
bos_pool_destroy(p);
printf("test_upload_file ok\n");
}