
# 下载对象(C SDK)
![](https://support.huaweicloud.com/sdk-c-devg-obs/public_sys-resources/notice_3.0-zh-cn.png)
开发过程中，您有任何问题可以在GitHub上[提交issue](https://github.com/huaweicloud/huaweicloud-sdk-c-obs/issues)，或者在[华为云对象存储服务论坛](https://bbs.huaweicloud.com/forum/forum-620-1.html)中发帖求助。
以下示例展示如何通过get_object将对象以文件形式下载到本地：
```
#include "eSDKOBS.h"
#include <stdio.h>
#include <sys/stat.h>
// 响应回调函数，可以在这个回调中把properties的内容记录到callback_data(用户自定义回调数据)中
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data);
obs_status get_object_data_callback(int buffer_size, const char *buffer,
    void *callback_data);
void get_object_complete_callback(obs_status status,
    const obs_error_details *error,
    void *callback_data);
typedef struct get_object_callback_data
{
    FILE *outfile;
    obs_status ret_status;
}get_object_callback_data;
FILE * write_to_file(char *localfile);
int main()
{
    // 以下示例展示如何通过get_object函数下载对象到本地文件：
    // 在程序入口调用obs_initialize方法来初始化网络、内存等全局资源。
    obs_status ret_status = obs_initialize(OBS_INIT_ALL);
    if (OBS_STATUS_OK != ret_status)
    {
        printf("obs_initialize failed(%s).\n", obs_get_status_name(ret_status));
        return -1;
    }
    obs_options options;
    // 创建并初始化options，该参数包括访问域名(host_name)、访问密钥（access_key_id和access_key_secret）、桶名(bucket_name)、桶存储类别(storage_class)等配置信息
    init_obs_options(&options);
    // host_name填写桶所在的endpoint, 此处以华北-北京四为例，其他地区请按实际情况填写。
    options.bucket_options.host_name = "obs.cn-north-4.myhuaweicloud.com";
    // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；
    // 本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY。
    options.bucket_options.access_key = getenv("ACCESS_KEY_ID");
    options.bucket_options.secret_access_key = getenv("SECRET_ACCESS_KEY");
    // 填写Bucket名称，例如example-bucket-name。
    char * bucket_name = "example-bucket-name";
    options.bucket_options.bucket_name = bucket_name;
    // 设置对象下载到本地的文件名
    char *file_name = "./example_get_file_test";
    obs_object_info object_info;
    // 设置下载的对象
    memset(&object_info, 0, sizeof(obs_object_info));
    object_info.key = "example_get_file_test";
    object_info.version_id = NULL;
    //根据业务需要设置存放下载对象数据的结构
    get_object_callback_data data;
    data.ret_status = OBS_STATUS_BUTT;
    data.outfile = write_to_file(file_name);
    // 定义范围下载参数
    obs_get_conditions getcondition;
    memset(&getcondition, 0, sizeof(obs_get_conditions));
    init_get_properties(&getcondition);
    // 下载起始位置，默认0，从对象0字节位置开始下载
    getcondition.start_byte = 0;
    // 下载长度，默认0，一直下载到对象尾
    // getcondition.byte_count = 0;
    // 定义下载的回调函数
    obs_get_object_handler get_object_handler =
    {
        { &response_properties_callback,
          &get_object_complete_callback},
        &get_object_data_callback
    };
    get_object(&options, &object_info, &getcondition, 0, &get_object_handler, &data);
    if (OBS_STATUS_OK == data.ret_status) {
        printf("get object successfully. \n");
    }
    else
    {
        printf("get object failed(%s).\n", obs_get_status_name(data.ret_status));
    }
    fclose(data.outfile);
    // 释放分配的全局资源
    obs_deinitialize();
}
// 响应回调函数，可以在这个回调中把properties的内容记录到callback_data(用户自定义回调数据)中
obs_status response_properties_callback(const obs_response_properties *properties, void *callback_data)
{
    if (properties == NULL)
    {
        printf("error! obs_response_properties is null!");
        return OBS_STATUS_OK;      
    }
    // 打印响应信息
#define print_nonnull(name, field)                                 \
    do {                                                           \
        if (properties-> field) {                                  \
            printf("%s: %s\n", name, properties->field);          \
        }                                                          \
    } while (0)
    print_nonnull("request_id", request_id);
    print_nonnull("request_id2", request_id2);
    print_nonnull("content_type", content_type);
    if (properties->content_length) {
        printf("content_length: %llu\n", properties->content_length);
    }
    print_nonnull("server", server);
    print_nonnull("ETag", etag);
    print_nonnull("expiration", expiration);
    print_nonnull("website_redirect_location", website_redirect_location);
    print_nonnull("version_id", version_id);
    print_nonnull("allow_origin", allow_origin);
    print_nonnull("allow_headers", allow_headers);
    print_nonnull("max_age", max_age);
    print_nonnull("allow_methods", allow_methods);
    print_nonnull("expose_headers", expose_headers);
    print_nonnull("storage_class", storage_class);
    print_nonnull("server_side_encryption", server_side_encryption);
    print_nonnull("kms_key_id", kms_key_id);
    print_nonnull("customer_algorithm", customer_algorithm);
    print_nonnull("customer_key_md5", customer_key_md5);
    print_nonnull("bucket_location", bucket_location);
    print_nonnull("obs_version", obs_version);
    print_nonnull("restore", restore);
    print_nonnull("obs_object_type", obs_object_type);
    print_nonnull("obs_next_append_position", obs_next_append_position);
    print_nonnull("obs_head_epid", obs_head_epid);
    print_nonnull("reserved_indicator", reserved_indicator);
    int i;
    for (i = 0; i < properties->meta_data_count; i++) {
        printf("x-obs-meta-%s: %s\n", properties->meta_data[i].name,
            properties->meta_data[i].value);
    }
    return OBS_STATUS_OK;
}
obs_status get_object_data_callback(int buffer_size, const char *buffer,
    void *callback_data)
{
    get_object_callback_data *data = (get_object_callback_data *)callback_data;
    size_t wrote = fwrite(buffer, 1, buffer_size, data->outfile);
    return ((wrote < (size_t)buffer_size) ?
        OBS_STATUS_AbortedByCallback : OBS_STATUS_OK);
}
void get_object_complete_callback(obs_status status,
    const obs_error_details *error,
    void *callback_data)
{
    get_object_callback_data *data = (get_object_callback_data *)callback_data;
    data->ret_status = status;
}
FILE * write_to_file(char *localfile)
{
    FILE *outfile = 0;
    if (localfile) {
        struct stat buf;
        if (stat(localfile, &buf) == -1) {
            outfile = fopen(localfile, "wb");
        }
        else {
            outfile = fopen(localfile, "a");
        }
        if (!outfile) {
            fprintf(stderr, "\nERROR: Failed to open output file %s: ",
                localfile);
            return outfile;
        }
    } else {
        fprintf(stderr, "\nERROR: Failed to open output file, it's NULL, write object to stdout.",
            localfile);
        outfile = stdout;
    }
    return outfile;
}
```
![](https://support.huaweicloud.com/sdk-c-devg-obs/public_sys-resources/note_3.0-zh-cn.png)
更多下载对象的信息，请参见[下载对象](https://support.huaweicloud.com/sdk-c-devg-obs/obs_20_0501.html)。
