开发者社区> 问答> 正文

C-SDK之如何实现上传文件(三)?

分步完成分片上传


分步完成分片上传的好处是灵活,一般的流程如下:

  1. 初始化一个分片上传任务(oss_init_multipart_upload)
  2. 逐个或并行上传分片(oss_upload_part_from_file)
  3. 完成上传(oss_complete_multipart_upload)


初始化


初始化一个分片上传事件
  1. void init_multipart_upload()
  2. {
  3.     aos_pool_t *p = NULL;
  4.     aos_string_t bucket;
  5.     aos_string_t object;
  6.     aos_table_t *headers = NULL;
  7.     aos_table_t *resp_headers = NULL;
  8.     oss_request_options_t *options = NULL;
  9.     aos_string_t upload_id;
  10.     oss_upload_file_t *upload_file = NULL;
  11.     aos_status_t *s = NULL;
  12.     oss_list_upload_part_params_t *params = NULL;
  13.     aos_list_t complete_part_list;
  14.     oss_list_part_content_t *part_content = NULL;
  15.     aos_pool_create(&p, NULL);
  16.     /* 创建并初始化options */
  17.     options = oss_request_options_create(p);
  18.     init_options(options);
  19.     /* 初始化参数 */
  20.     headers = aos_table_make(p, 1);
  21.     aos_str_set(&bucket, "<您的bucket名字>");
  22.     aos_str_set(&object, "<您的object名字>");
  23.     /* 初始化分片上传,获取一个上传ID */
  24.     s = oss_init_multipart_upload(options, &bucket, &object,
  25.                                   &upload_id, headers, &resp_headers);
  26.     /* 判断是否初始化分片上传成功 */
  27.     if (aos_status_is_ok(s)) {
  28.         printf("Init multipart upload succeeded, upload_id:%.*s\n",
  29.                upload_id.len, upload_id.data);
  30.     } else {
  31.         printf("Init multipart upload failed, upload_id:%.*s\n",
  32.                upload_id.len, upload_id.data);
  33.     }
  34.     /* 上传每一个分片,代码参考下一节,这里省略*/
  35.     /* 完成分片上传,代码参考后面章节,这里省略*/
  36.     /* 释放资源*/
  37.     aos_pool_destroy(p);
  38. }

注:
  • 返回结果中含有uplolad_id ,它是区分分片上传事件的唯一标识,在后面的操作中,我们将用到它。
  • 上述代码只是演示如何初始化分片上传,只是部分代码,完整的代码参考下面的GitHub链接。
  • 完整代码参考:GitHub
  • 1.0.0版本中的参数顺序是…headers, upload_id…,2.0.0版本中的参数顺序是…upload_id,headers…


本地上传分片


接着,把本地文件分片上传。
  1. void multipart_upload_file()
  2. {
  3.     aos_pool_t *p = NULL;
  4.     aos_string_t bucket;
  5.     aos_string_t object;
  6.     int is_cname = 0;
  7.     aos_table_t *headers = NULL;
  8.     aos_table_t *complete_headers = NULL;
  9.     aos_table_t *resp_headers = NULL;
  10.     oss_request_options_t *options = NULL;
  11.     aos_string_t upload_id;
  12.     oss_upload_file_t *upload_file = NULL;
  13.     aos_status_t *s = NULL;
  14.     oss_list_upload_part_params_t *params = NULL;
  15.     aos_list_t complete_part_list;
  16.     oss_list_part_content_t *part_content = NULL;
  17.     oss_complete_part_content_t *complete_part_content = NULL;
  18.     int part_num1 = 1;
  19.     int part_num2 = 2;
  20.     aos_pool_create(&p, NULL);
  21.     /* 创建并初始化options */
  22.     options = oss_request_options_create(p);
  23.     init_options(options);
  24.     /* 初始化参数 */
  25.     headers = aos_table_make(p, 1);
  26.     resp_headers = aos_table_make(options->pool, 5);
  27.     aos_str_set(&bucket, "<您的bucket名字>");
  28.     aos_str_set(&object, "<您的object名字>");
  29.     /* 初始化分片上传,获取upload id,代码参考前面章节,这里省略*/
  30.     /* 上传第一个分片 */
  31.     upload_file = oss_create_upload_file(p);
  32.     aos_str_set(&upload_file->filename, MULTIPART_UPLOAD_FILE_PATH);
  33.     upload_file->file_pos = 0;
  34.     upload_file->file_last = 200 * 1024; //200k
  35.     s = oss_upload_part_from_file(options, &bucket, &object, &upload_id,
  36.         part_num1, upload_file, &resp_headers);    
  37.     /* 判断是否上传分片成功 */
  38.     if (aos_status_is_ok(s)) {
  39.         printf("Multipart upload from file succeeded\n");
  40.     } else {
  41.         printf("Multipart upload from file failed\n");
  42.     }
  43.     /* 上传第二个分片 */
  44.     upload_file->file_pos = 200 *1024;//remain content start pos
  45.     upload_file->file_last = get_file_size(MULTIPART_UPLOAD_FILE_PATH);
  46.     s = oss_upload_part_from_file(options, &bucket, &object, &upload_id,
  47.         part_num2, upload_file, &resp_headers);
  48.     /* 判断是否上传分片成功 */
  49.     if (aos_status_is_ok(s)) {
  50.         printf("Multipart upload from file succeeded\n");
  51.     } else {
  52.         printf("Multipart upload from file failed\n");
  53.     }
  54.     /* 完成分片上传,代码参考下一章节,这里省略*/
  55.     /* 释放资源*/
  56.     aos_pool_destroy(p);
  57. }

上面程序的核心是调用oss_upload_part_from_file接口来上传每一个分片。

注:
  • oss_upload_part_from_file接口要求除最后一个分片以外,其他的分片大小都要大于100KB。
  • 分片号码的范围是1~10000。如果超出这个范围,OSS将返回InvalidArgument的错误码。
  • 每次上传分片时都要把流定位到此次上传分片开头所对应的位置。
  • 上述代码只是演示如何初始化分片上传,只是部分代码,完整的代码参考下面的GitHub链接。
  • 完整代码参考:GitHub


获取已上传的分片,完成分片上传

  1. void complete_multipart_upload()
  2. {
  3.     aos_pool_t *p = NULL;
  4.     aos_string_t bucket;
  5.     aos_string_t object;
  6.     aos_table_t *complete_headers = NULL;
  7.     aos_table_t *resp_headers = NULL;
  8.     oss_request_options_t *options = NULL;
  9.     aos_string_t upload_id;
  10.     aos_status_t *s = NULL;
  11.     oss_list_upload_part_params_t *params = NULL;
  12.     aos_list_t complete_part_list;
  13.     oss_list_part_content_t *part_content = NULL;
  14.     oss_complete_part_content_t *complete_part_content = NULL;
  15.     aos_pool_create(&p, NULL);
  16.     /* 创建并初始化options */
  17.     options = oss_request_options_create(p);
  18.     init_options(options);
  19.     /* 初始化参数 */
  20.     headers = aos_table_make(p, 1);
  21.     resp_headers = aos_table_make(options->pool, 5);
  22.     aos_str_set(&bucket, "<您的bucket名字>");
  23.     aos_str_set(&object, "<您的object名字>");
  24.     /* 初始化分片上传,获取一个Upload Id,代码参考上面章节,这里省略*/
  25.     /* 上传每个分片,代码参考上面章节,这里省略*/
  26.     /* 获取已经上传的分片
  27.      * 调用oss_complete_multipart_upload接口时需要每个分片的ETag值,这个值有两种获取途径:
  28.      * 第一种是上传每个分片的时候,返回结果里面会包含这个分片的ETag值,可以保存下来,等后面使用;
  29.      * 第二种是通过调用oss_list_upload_part接口获取已经上传的分片的ETag值。
  30.      * 下面演示的是第二种方式
  31.      */
  32.     params = oss_create_list_upload_part_params(p);
  33.     params->max_ret = 1000;
  34.     aos_list_init(&complete_part_list);
  35.     s = oss_list_upload_part(options, &bucket, &object, &upload_id,
  36.                              params, &resp_headers);
  37.     /* 判断是否获取分片列表成功 */
  38.     if (aos_status_is_ok(s)) {
  39.         printf("List multipart succeeded\n");
  40.     } else {
  41.         printf("List multipart failed\n");
  42.     }
  43.     aos_list_for_each_entry(part_content, &params->part_list, node) {
  44.         complete_part_content = oss_create_complete_part_content(p);
  45.         aos_str_set(&complete_part_content->part_number,
  46.                     part_content->part_number.data);
  47.         aos_str_set(&complete_part_content->etag, part_content->etag.data);
  48.         aos_list_add_tail(&complete_part_content->node, &complete_part_list);
  49.     }
  50.     /* 完成分片上传 */
  51.     s = oss_complete_multipart_upload(options, &bucket, &object, &upload_id,
  52.             &complete_part_list, complete_headers, &resp_headers);
  53.     /* 判断完成分片上传是否成功 */
  54.     if (aos_status_is_ok(s)) {
  55.         printf("Complete multipart upload from file succeeded, upload_id:%.*s\n",
  56.                upload_id.len, upload_id.data);
  57.     } else {
  58.         printf("Complete multipart upload from file failed\n");
  59.     }
  60.     /* 释放资源 */
  61.     aos_pool_destroy(p);
  62. }

注:
  • 2.0.0相对于1.0.0版本,oss_complete_multipart_upload接口增加了headers参数,用来在完成时修改headers值
  • 完整代码参考:GitHub



展开
收起
青衫无名 2017-10-19 10:50:51 1894 0
0 条回答
写回答
取消 提交回答
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
从 SDK 到编解码:视频直播架构解析 立即下载
跨平台的云服务SDK需要什么 立即下载
一个跨平台的云服务SDK需要什么 立即下载