分片下载

本SDK提供ufile_download_piece方法用于从US3的存储空间下载文件到本地,适用于大文件下载,完整代码详见 Github

ufile_download调用的 US3 API 为GetFile, 具体参见GetFile API文档

方法原型

1
struct ufile_error ufile_download_piece(const char *bucket_name, const char *key, size_t start_position, char *buf, size_t buf_len, size_t *return_size)

参数说明

  • bucket_name: 待下载分片所属文件所在的存储空间的名称
  • key: 待下载分片所属文件在存储空间里的名称
  • start_position: 当前待下载分片在文件中的字节偏移量
  • buf_len: 待下载分片的字节数

示例

以下代码展示了如何通过分片下载下载大文件到本地的流程。

执行该示例请先配置UFILE_*相关环境变量并赋予bucket_namekeyfile_path有效值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "../lib/api.h"
#include <stdio.h>
#include <stdlib.h>
#define fourMegabyte 1 << 22 //4M

const char* bucket_name = "csdk-create-bucket";
const char* key = "ufile_put_file";
const char* file_path = "ufile_download_piece.txt";

int main(int argc, char *argv[]){
    // 读取配置初始化SDK
    struct ufile_config cfg;
    cfg.public_key = getenv("UFILE_PUBLIC_KEY");
    cfg.private_key = getenv("UFILE_PRIVATE_KEY");
    cfg.bucket_host = getenv("UFILE_BUCKET_HOST");
    cfg.file_host = getenv("UFILE_FILE_HOST");
    struct ufile_error error;
    error = ufile_sdk_initialize(cfg, 0);
    if(UFILE_HAS_ERROR(error.code)){
        printf("初始化 sdk 失败,错误信息为:%s\n", error.message);
        return 1;
    }

    // 创建本地文件(追加写)
    FILE *fp = fopen(file_path, "a+");
    if (fp == NULL){
        fprintf(stderr, "打开文件失败, 错误信息为: %s\n", strerror(errno));
        return 1;
    }

    // 分片下载
    char buf[fourMegabyte]; 
    size_t pos = 0;		// 当前下载分片在文件中的字节偏移量
    size_t return_size; // 实际下载的字节数
    while(!UFILE_HAS_ERROR(error.code)){
        error = ufile_download_piece(bucket_name, key, pos, buf, fourMegabyte, &return_size);
        size_t nc = fwrite(buf, 1, return_size, fp); // 写入文件
        if(return_size < fourMegabyte){ //若实际下载的字节数小于buf大小,则表示已经读到了文件结尾。
            printf("return_size < fourMegabyte: %d < %d \n", return_size, fourMegabyte);
            break;
        }
        pos += fourMegabyte; 
        sleep(1); 
    }
    fclose(fp);
    if(UFILE_HAS_ERROR(error.code)){
        printf("调用 ufile_download_piece 失败,错误信息为:%s\n", error.message);
        ufile_sdk_cleanup();
        return 1;
    }
    
    // 释放初始化SDK时分配的内存
    ufile_sdk_cleanup();
    return 0;
}