分步完成分片上传
分步完成分片上传的好处是灵活,一般的流程如下:
- 初始化一个分片上传任务(oss_init_multipart_upload)
- 逐个或并行上传分片(oss_upload_part_from_file)
- 完成上传(oss_complete_multipart_upload)
初始化
初始化一个分片上传事件
- void init_multipart_upload()
- {
- aos_pool_t *p = NULL;
- aos_string_t bucket;
- aos_string_t object;
- aos_table_t *headers = NULL;
- aos_table_t *resp_headers = NULL;
- oss_request_options_t *options = NULL;
- aos_string_t upload_id;
- oss_upload_file_t *upload_file = NULL;
- aos_status_t *s = NULL;
- oss_list_upload_part_params_t *params = NULL;
- aos_list_t complete_part_list;
- oss_list_part_content_t *part_content = NULL;
- aos_pool_create(&p, NULL);
- /* 创建并初始化options */
- options = oss_request_options_create(p);
- init_options(options);
- /* 初始化参数 */
- headers = aos_table_make(p, 1);
- aos_str_set(&bucket, "<您的bucket名字>");
- aos_str_set(&object, "<您的object名字>");
- /* 初始化分片上传,获取一个上传ID */
- s = oss_init_multipart_upload(options, &bucket, &object,
- &upload_id, headers, &resp_headers);
- /* 判断是否初始化分片上传成功 */
- if (aos_status_is_ok(s)) {
- printf("Init multipart upload succeeded, upload_id:%.*s\n",
- upload_id.len, upload_id.data);
- } else {
- printf("Init multipart upload failed, upload_id:%.*s\n",
- upload_id.len, upload_id.data);
- }
- /* 上传每一个分片,代码参考下一节,这里省略*/
- /* 完成分片上传,代码参考后面章节,这里省略*/
- /* 释放资源*/
- aos_pool_destroy(p);
- }
注:
- 返回结果中含有uplolad_id ,它是区分分片上传事件的唯一标识,在后面的操作中,我们将用到它。
- 上述代码只是演示如何初始化分片上传,只是部分代码,完整的代码参考下面的GitHub链接。
- 完整代码参考:GitHub
- 1.0.0版本中的参数顺序是…headers, upload_id…,2.0.0版本中的参数顺序是…upload_id,headers…
本地上传分片
接着,把本地文件分片上传。
- void multipart_upload_file()
- {
- aos_pool_t *p = NULL;
- aos_string_t bucket;
- aos_string_t object;
- int is_cname = 0;
- aos_table_t *headers = NULL;
- aos_table_t *complete_headers = NULL;
- aos_table_t *resp_headers = NULL;
- oss_request_options_t *options = NULL;
- aos_string_t upload_id;
- oss_upload_file_t *upload_file = NULL;
- aos_status_t *s = NULL;
- oss_list_upload_part_params_t *params = NULL;
- aos_list_t complete_part_list;
- oss_list_part_content_t *part_content = NULL;
- oss_complete_part_content_t *complete_part_content = NULL;
- int part_num1 = 1;
- int part_num2 = 2;
- aos_pool_create(&p, NULL);
- /* 创建并初始化options */
- options = oss_request_options_create(p);
- init_options(options);
- /* 初始化参数 */
- headers = aos_table_make(p, 1);
- resp_headers = aos_table_make(options->pool, 5);
- aos_str_set(&bucket, "<您的bucket名字>");
- aos_str_set(&object, "<您的object名字>");
- /* 初始化分片上传,获取upload id,代码参考前面章节,这里省略*/
- /* 上传第一个分片 */
- upload_file = oss_create_upload_file(p);
- aos_str_set(&upload_file->filename, MULTIPART_UPLOAD_FILE_PATH);
- upload_file->file_pos = 0;
- upload_file->file_last = 200 * 1024; //200k
- s = oss_upload_part_from_file(options, &bucket, &object, &upload_id,
- part_num1, upload_file, &resp_headers);
- /* 判断是否上传分片成功 */
- if (aos_status_is_ok(s)) {
- printf("Multipart upload from file succeeded\n");
- } else {
- printf("Multipart upload from file failed\n");
- }
- /* 上传第二个分片 */
- upload_file->file_pos = 200 *1024;//remain content start pos
- upload_file->file_last = get_file_size(MULTIPART_UPLOAD_FILE_PATH);
- s = oss_upload_part_from_file(options, &bucket, &object, &upload_id,
- part_num2, upload_file, &resp_headers);
- /* 判断是否上传分片成功 */
- if (aos_status_is_ok(s)) {
- printf("Multipart upload from file succeeded\n");
- } else {
- printf("Multipart upload from file failed\n");
- }
- /* 完成分片上传,代码参考下一章节,这里省略*/
- /* 释放资源*/
- aos_pool_destroy(p);
- }
上面程序的核心是调用oss_upload_part_from_file接口来上传每一个分片。
注:
- oss_upload_part_from_file接口要求除最后一个分片以外,其他的分片大小都要大于100KB。
- 分片号码的范围是1~10000。如果超出这个范围,OSS将返回InvalidArgument的错误码。
- 每次上传分片时都要把流定位到此次上传分片开头所对应的位置。
- 上述代码只是演示如何初始化分片上传,只是部分代码,完整的代码参考下面的GitHub链接。
- 完整代码参考:GitHub
获取已上传的分片,完成分片上传
- void complete_multipart_upload()
- {
- aos_pool_t *p = NULL;
- aos_string_t bucket;
- aos_string_t object;
- aos_table_t *complete_headers = NULL;
- aos_table_t *resp_headers = NULL;
- oss_request_options_t *options = NULL;
- aos_string_t upload_id;
- aos_status_t *s = NULL;
- oss_list_upload_part_params_t *params = NULL;
- aos_list_t complete_part_list;
- oss_list_part_content_t *part_content = NULL;
- oss_complete_part_content_t *complete_part_content = NULL;
- aos_pool_create(&p, NULL);
- /* 创建并初始化options */
- options = oss_request_options_create(p);
- init_options(options);
- /* 初始化参数 */
- headers = aos_table_make(p, 1);
- resp_headers = aos_table_make(options->pool, 5);
- aos_str_set(&bucket, "<您的bucket名字>");
- aos_str_set(&object, "<您的object名字>");
- /* 初始化分片上传,获取一个Upload Id,代码参考上面章节,这里省略*/
- /* 上传每个分片,代码参考上面章节,这里省略*/
- /* 获取已经上传的分片
- * 调用oss_complete_multipart_upload接口时需要每个分片的ETag值,这个值有两种获取途径:
- * 第一种是上传每个分片的时候,返回结果里面会包含这个分片的ETag值,可以保存下来,等后面使用;
- * 第二种是通过调用oss_list_upload_part接口获取已经上传的分片的ETag值。
- * 下面演示的是第二种方式
- */
- params = oss_create_list_upload_part_params(p);
- params->max_ret = 1000;
- aos_list_init(&complete_part_list);
- s = oss_list_upload_part(options, &bucket, &object, &upload_id,
- params, &resp_headers);
- /* 判断是否获取分片列表成功 */
- if (aos_status_is_ok(s)) {
- printf("List multipart succeeded\n");
- } else {
- printf("List multipart failed\n");
- }
- aos_list_for_each_entry(part_content, ¶ms->part_list, node) {
- complete_part_content = oss_create_complete_part_content(p);
- aos_str_set(&complete_part_content->part_number,
- part_content->part_number.data);
- aos_str_set(&complete_part_content->etag, part_content->etag.data);
- aos_list_add_tail(&complete_part_content->node, &complete_part_list);
- }
- /* 完成分片上传 */
- s = oss_complete_multipart_upload(options, &bucket, &object, &upload_id,
- &complete_part_list, complete_headers, &resp_headers);
- /* 判断完成分片上传是否成功 */
- if (aos_status_is_ok(s)) {
- printf("Complete multipart upload from file succeeded, upload_id:%.*s\n",
- upload_id.len, upload_id.data);
- } else {
- printf("Complete multipart upload from file failed\n");
- }
- /* 释放资源 */
- aos_pool_destroy(p);
- }
注:
- 2.0.0相对于1.0.0版本,oss_complete_multipart_upload接口增加了headers参数,用来在完成时修改headers值
- 完整代码参考:GitHub