开发者社区> 问答> 正文

C-SDK 之如何实现下载文件(二)?


分段下载文件


通过设置Range指定返回文件的传输范围,可以实现文件的分段下载。以下代码实现分段下载文件到内存中: aos_pool_t *p;
oss_request_options_t *options;
aos_status_t *s;
aos_table_t *headers;
aos_table_t *params;
aos_table_t *resp_headers;
char *bucket_name = "<您的bucket名字>";
char *object_name = "<您的object名字>";
aos_string_t bucket;
aos_string_t object;
aos_list_t buffer;
aos_pool_create(&p, NULL);
/* 创建并初始化options */
options = oss_request_options_create(p);
init_options(options);
/* 初始化参数 */
aos_str_set(&bucket, bucket_name);
aos_str_set(&object, object_name);
params = NULL;
headers = aos_table_make(p, 1);
/* 设置Range,读取文件的指定范围,bytes=20-100包括第20和第100个字符 */
apr_table_set(headers, "Range", "bytes=20-100");
aos_list_init(&buffer);
/* 分片下载文件 */
s = oss_get_object_to_buffer(options, &bucket, &object, headers, params, &buffer, &resp_headers);
if (aos_status_is_ok(s)) {
    printf("get object succeeded\n");
} else {
    printf("get object failed\n");
}
aos_pool_destroy(p);



断点续传下载


大文件下载时,如果网络不稳定或者发生其它异常,则整个下载会失败。用户不得不重新下载,造成浪费资源,而且在网络不稳定的情况下,往往要重试多次。断点续传下载,支持并发、断点续传,通过 oss_resumable_clt_params_t 控制断点续传的行为,它有以下参数:

  • part_size 分片大小,从1B到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_download_with_resumable()
{
    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;
    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_2.zip");
    aos_str_set(&filename, "local_big_file_2.zip");
    // download
    clt_params = oss_create_resumable_clt_params_content(p, 1024 * 100, 3, AOS_TRUE, NULL);
    s = oss_resumable_download_file(options, &bucket, &object, &filename, headers, NULL,
        clt_params, NULL, &resp_headers);
    if (aos_status_is_ok(s)) {
        printf("download succeeded\n");
    } else {
        printf("download failed\n");
    }
    aos_pool_destroy(p);
}


[backcolor=transparent]注:
  • 断点续传下载支持进度条功能。
  • 完整代码参考:GitHub


进度条


OSS C SDK支持进度条功能,指示上传/下载的进度。下面的代码以GetObject为例,说明进度条功能的使用方法。 void percentage(int64_t consumed_bytes, int64_t total_bytes)
{
    assert(total_bytes >= consumed_bytes);
    printf("%%%" APR_INT64_T_FMT "\n", consumed_bytes * 100 / total_bytes);
}
void put_and_get_from_file_with_progress()
{
    aos_pool_t *p = NULL;
    aos_status_t *s = NULL;
    int is_cname = 0;
    aos_string_t bucket;
    aos_string_t object;
    aos_string_t filename;
    oss_request_options_t *options = NULL;
    aos_table_t *resp_headers = NULL;
    aos_list_t resp_body;
    char *download_filename = "get_object_to_local_file.txt";
    /* init test*/
    aos_pool_create(&p, NULL);
    options = oss_request_options_create(p);
    init_sample_request_options(options, is_cname);
    aos_str_set(&bucket, BUCKET_NAME);
    aos_str_set(&object, OBJECT_NAME);
    aos_str_set(&filename, __FILE__);
    aos_list_init(&resp_body);
    /* put object */
    s = oss_do_put_object_from_file(options, &bucket, &object, &filename, NULL, NULL, percentage, &resp_headers, &resp_body);
    if (aos_status_is_ok(s)) {
        printf("put object from file succeeded\n");
    } else {
        printf("put object from file failed\n");
        aos_pool_destroy(p);
        return;
    }
    aos_pool_destroy(p);
    /* get object */
    aos_pool_create(&p, NULL);
    options = oss_request_options_create(p);
    init_sample_request_options(options, is_cname);
    aos_str_set(&filename, download_filename);
    s = oss_do_get_object_to_file(options, &bucket, &object, NULL, NULL, &filename, percentage, NULL);
    if (aos_status_is_ok(s)) {
        printf("get object to file succeeded\n");
    } else {
        printf("get object to file failed\n");
    }
    aos_pool_destroy(p);
}


[backcolor=transparent]注:
  • oss_do_get_object_to_buffer、oss_do_put_object_from_file支持进度条功能,代码请参考:GitHub

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

相关电子书

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