开发者社区> 问答> 正文

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


从本地文件追加数据到OSS


通过oss_append_object_from_file接口,并指定fliepath参数, 可以实现将一个本地文件的数据追加到OSS: void append_object_from_file()
{
    aos_pool_t *p = NULL;
    aos_string_t bucket;
    aos_string_t object;
    aos_table_t *headers1 = NULL;
    aos_table_t *headers2 = NULL;
    aos_table_t *resp_headers = NULL;
    oss_request_options_t *options = NULL;
    char *filename = __FILE__;
    aos_status_t *s = NULL;
    aos_string_t file;
    int64_t position = 0;
    char *next_append_position = NULL;
    aos_pool_create(&p, NULL);
    /* 创建并初始化options */
    options = oss_request_options_create(p);
    init_options(options);
    /* 初始化参数 */
    headers1 = aos_table_make(options->pool, 0);
    headers2 = aos_table_make(options->pool, 0);
    aos_str_set(&bucket, "<您的bucket名字>");
    aos_str_set(&object, "<您的object名字>");
    aos_str_set(&file, filename);
    /* 获取起始追加位置 */
    s = oss_head_object(options, &bucket, &object, headers1, &resp_headers);
    if(aos_status_is_ok(s)) {
        next_append_position = (char*)(apr_table_get(resp_headers,
                        "x-oss-next-append-position"));
        position = atoi(next_append_position);
    }
    /* 追加文件 */
    s = oss_append_object_from_file(options, &bucket, &object,
                                    position, &file, headers2, &resp_headers);
    /* 判断是否追加成功 */
    if (aos_status_is_ok(s)) {
        printf("append object from file succeeded\n");
    } else {
        printf("append object from file failed\n");
    }    
    /* 释放资源*/
    aos_pool_destroy(p);
}

[backcolor=transparent]注:
  • 不能对一个非Appendable Object进行Append Object操作。例如,已经存在一个同名Normal Object时,Append Object调用返回409,错误码ObjectNotAppendable。
  • 对一个已经存在的Appendable Object进行Put Object操作,那么该Appendable Object会被新的Object覆盖,类型变为Normal Object。
  • Head Object操作会返回x-oss-object-type,用于表明Object的类型。对于Appendable Object来说,该值为Appendable。对Appendable Object,Head Object也会返回上述的x-oss-next-append-position和x-oss-hash-crc64ecma。
  • 不能使用Copy Object来拷贝一个Appendable Object,也不能改变它的服务器端加密的属性。可以使用Copy Object来改变用户自定义元信息。
  • 完整代码参考:GitHub


断点续传上传


大文件上传时,网络不稳定或者其它异常发生,则整个上传就会失败。用户不得不重新上传,造成浪费资源;在网络不稳定的情况下,往往要重试多次。断点续传上传,支持并发、断点续传。断点续传上传通过 oss_resumable_clt_params_t控制并发、断点续传的行为,它有以下参数:
  • part_size 分片大小,从100KB到5GB,单位是[backcolor=transparent]byte
  • thread_num 并发线程数,默认为[backcolor=transparent]1
  • enable_checkpoint 是否开启断点续传,[backcolor=transparent]默认不开启
  • checkpoint_path checkpoint文件的路径,默认放在上传文件目录下{upload_file_path}.cp

断点续传上传的实现原理是,将要上传文件分成若干个分片分别上传,所有分片上传成功后,完成整个文件的上传。在上传的过程中会记录当前上传的进度信息(记录在checkpoint文件中),如果上传过程中某一分片上传失败,再次上传时会从checkpoint文件中记录的断点继续上传。这要求再次调用时要指定与上次相同的checkpoint文件。上传完成后,checkpoint文件会被删除。 void resumable_upload()
{
    aos_pool_t *p = NULL;
    aos_string_t bucket;
    aos_string_t object;
    aos_string_t filename;
    aos_status_t *s = NULL;
    int is_cname = 0;
    aos_table_t *headers = NULL;
    aos_table_t *resp_headers = NULL;
    aos_list_t resp_body;
    oss_request_options_t *options = NULL;
    oss_resumable_clt_params_t *clt_params;
    aos_pool_create(&p, NULL);
    options = oss_request_options_create(p);
    init_sample_request_options(options, is_cname);
    headers = aos_table_make(p, 0);
    aos_str_set(&bucket, BUCKET_NAME);
    aos_str_set(&object, "my_key.zip");
    aos_str_set(&filename, "local_big_file.zip");
    aos_list_init(&resp_body);
    // 断点续传
    clt_params = oss_create_resumable_clt_params_content(p, 1024 * 100, 3, AOS_TRUE, NULL);
    s = oss_resumable_upload_file(options, &bucket, &object, &filename, headers, NULL,
        clt_params, NULL, &resp_headers, &resp_body);
    if (aos_status_is_ok(s)) {
        printf("upload succeeded\n");
    } else {
        printf("upload failed\n");
    }
    aos_pool_destroy(p);
}

[backcolor=transparent]注:
  • 断点续传上传支持设置元信息、上传回调、进度条功能。
  • 完整代码参考:GitHub


分片上传


除了通过简单上传将文件上传到OSS以外,OSS还提供了另外一种上传模式 —— 分片上传。用户可以在如下的应用场景内(但不仅限于此),使用分片上传模式,如:
  • 需要支持断点上传。
  • 上传超过100MB大小的文件。
  • 网络条件较差,和OSS的服务器之间的连接经常断开。
  • 需要流式地上传文件。上传文件之前,无法确定上传文件的大小。


易用接口完成分片上传


为了方便用户完成分片上传,下面代码通过封装后的易用接口oss_upload_file进行分片上传文件操作。 void test_upload_file()
{
    aos_pool_t *p = NULL;
    aos_string_t bucket;
    aos_string_t object;
    oss_request_options_t *options = NULL;
    aos_status_t *s = NULL;
    int part_size = 100 * 1024;
    aos_string_t upload_id;
    aos_string_t filepath;
    aos_pool_create(&p, NULL);
    /* 创建并初始化options */
    options = oss_request_options_create(p);
    init_options(options);
    aos_str_set(&bucket, "<您的bucket名字>");
    aos_str_set(&object, "<您的object名字>");
    aos_str_null(&upload_id);
    aos_str_set(&filepath, __FILE__);
    /* 分片上传 */
    s = oss_upload_file(options, &bucket, &object, &upload_id, &filepath,
                        part_size, NULL);
    /* 判断是否上传成功 */
    if (aos_status_is_ok(s)) {
        printf("upload file succeeded\n");
    } else {
        printf("upload file failed\n");
    }  
    /* 释放资源*/
    aos_pool_destroy(p);
}

[backcolor=transparent]注:
  • 使用oss_upload_file进行分片上传文件操作,如果是一个新的分片上传操作,设置upload_id为NULL,可以通过aos_str_null(&upload_id)实现;如果是对一个已经存在的upload_id进行续传操作,设置upload_id为指定的upload_id_str,可以通过aos_str_set(&upload_id, upload_id_str)实现。
  • 使用oss_upload_file进行分片上传文件操作时,需要指定分片大小, 分片大小要大于100KB。分片号码的范围是1~10000,如果在切分文件时,发现分片号码的范围超出这个范围,oss_upload_file将自动调整分片大小。
  • 使用oss_upload_file进行分片上传文件操作,如果指定的upload_id已经存在,那么本次分片上传的分片大小要和指定upload_id的分片大小保持一致。
  • 完整代码参考:GitHub




展开
收起
青衫无名 2017-10-19 10:50:06 1891 0
0 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

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