全部产品
对象存储 OSS

管理文件

更新时间:2017-06-07 13:26:11   分享:   

查看所有文件

通过oss_list_object接口,可以列出当前存储空间下的所有文件。

  1. aos_pool_t *p;
  2. oss_request_options_t *options;
  3. aos_status_t *s;
  4. aos_table_t *resp_headers;
  5. char *bucket_name = "<您的bucket名字>";
  6. aos_string_t bucket;
  7. oss_list_object_params_t *params;
  8. oss_list_object_content_t *content;
  9. int max_ret = 1000;
  10. char *key;
  11. aos_pool_create(&p, NULL);
  12. options = oss_request_options_create(p);
  13. init_options(options);
  14. aos_str_set(&bucket, bucket_name);
  15. params = oss_create_list_object_params(p);
  16. params->max_ret = max_ret;
  17. aos_str_set(&params->prefix, "<查看文件的前缀>");
  18. aos_str_set(&params->delimiter, "<查看文件的分隔符>");
  19. aos_str_set(&params->marker, "<查看文件的起点>");
  20. s = oss_list_object(options, &bucket, params, &resp_headers);
  21. if (aos_status_is_ok(s)) {
  22. printf("get object succeeded\n");
  23. /* 下载文件 */
  24. aos_list_for_each_entry(content, &params->object_list, node) {
  25. key = apr_psprintf(p, "%.*s", content->key.len, content->key.data);
  26. }
  27. } else {
  28. printf("get object failed\n");
  29. }
  30. aos_pool_destroy(p);

注:

  • 默认情况下,如果存储空间中的文件数量大于1000,则只会返回1000个文件, 且返回结果中 truncated为true,并返回next_marker作为下此读取的起点。若想增大返回文件数目,可以修改 max_ret参数,或者使用marker参数分次读取。
  • 完整代码参考:GitHub

创建模拟目录

OSS是基于对象的存储服务,没有目录的概念。创建模拟目录本质上来说是创建了一个size为0的文件。对于这个文件照样可以上传下载,只是控制台会对以”/“结尾的文件以文件夹的方式展示,所以用户可以使用上述方式来实现创建模拟目录。

  1. aos_pool_t *p;
  2. oss_request_options_t *options;
  3. aos_status_t *s;
  4. aos_table_t *headers;
  5. aos_table_t *resp_headers;
  6. char *bucket_name = "<您的bucket名字>";
  7. char *object_name = "<您的文件夹名字/>";
  8. aos_string_t bucket;
  9. aos_string_t object;
  10. char *data = "";
  11. aos_list_t buffer;
  12. aos_buf_t *content;
  13. aos_pool_create(&p, NULL);
  14. options = oss_request_options_create(p);
  15. init_options(options);
  16. aos_str_set(&bucket, bucket_name);
  17. aos_str_set(&object, object_name);
  18. headers = aos_table_make(p, 0);
  19. aos_list_init(&buffer);
  20. content = aos_buf_pack(options->pool, data, strlen(data));
  21. aos_list_add_tail(&content->node, &buffer);
  22. s = oss_put_object_from_buffer(options, &bucket, &object, &buffer, headers, &resp_headers);
  23. if (aos_status_is_ok(s)) {
  24. printf("create dir succeeded\n");
  25. } else {
  26. printf("create dir failed\n");
  27. }
  28. aos_pool_destroy(p);

注:

设定Object的Http Header

向OSS上传文件时,除了文件内容,还可以指定文件的一些属性信息,称为“元信息”。这些信息在上传时与文件一起存储,在下载时与文件一起返回。下面代码为文件设置了过期时间:

  1. aos_pool_t *p;
  2. oss_request_options_t *options;
  3. aos_status_t *s;
  4. aos_table_t *headers;
  5. aos_table_t *resp_headers;
  6. char *bucket_name = "<您的bucket名字>";
  7. char *object_name = "<您的object名字>";
  8. aos_string_t bucket;
  9. aos_string_t object;
  10. char *data = "<object content>";
  11. aos_list_t buffer;
  12. aos_buf_t *content;
  13. aos_pool_create(&p, NULL);
  14. options = oss_request_options_create(p);
  15. init_options(options);
  16. aos_str_set(&object, object_name);
  17. aos_str_set(&bucket, bucket_name);
  18. headers = aos_table_make(p, 0);
  19. /* 设置http header */
  20. headers = aos_table_make(p, 1);
  21. apr_table_set(headers, "Expires", "Fri, 28 Feb 2012 05:38:42 GMT");
  22. /* 读取数据到buffer中 */
  23. aos_list_init(&buffer);
  24. content = aos_buf_pack(options->pool, data, strlen(data));
  25. aos_list_add_tail(&content->node, &buffer);
  26. s = oss_put_object_from_buffer(options, &bucket, &object, &buffer, headers, &resp_headers);
  27. if (aos_status_is_ok(s)) {
  28. printf("put object succeeded\n");
  29. } else {
  30. printf("put object failed\n");
  31. }
  32. aos_pool_destroy(p);

注:

  • 可以设置Http Header有:Cache-Control 、 Content-Disposition 、Content-Encoding、 Expires 。它们的相关介绍见 RFC2616
  • 完整代码参考:GitHub

设置User Meta

OSS支持用户自定义Meta信息对文件进行描述。比如:

  1. aos_pool_t *p;
  2. oss_request_options_t *options;
  3. aos_status_t *s;
  4. aos_table_t *headers;
  5. aos_table_t *resp_headers;
  6. char *bucket_name = "<您的bucket名字>";
  7. char *object_name = "<您的object名字>";
  8. aos_string_t bucket;
  9. aos_string_t object;
  10. char *data = "<object content>";
  11. aos_list_t buffer;
  12. aos_buf_t *content;
  13. aos_pool_create(&p, NULL);
  14. options = oss_request_options_create(p);
  15. init_options(options);
  16. aos_str_set(&bucket, bucket_name);
  17. aos_str_set(&object, object_name);
  18. headers = aos_table_make(p, 1);
  19. /* 设置用户自定义meta */
  20. apr_table_set(headers, "x-oss-meta-author", "oss");
  21. /* 上传数据到OSS中 */
  22. aos_list_init(&buffer);
  23. content = aos_buf_pack(options->pool, data, strlen(data));
  24. aos_list_add_tail(&content->node, &buffer);
  25. s = oss_put_object_from_buffer(options, &bucket, &object, &buffer, headers, &resp_headers);
  26. if (aos_status_is_ok(s)) {
  27. printf("put object succeeded\n");
  28. } else {
  29. printf("put object failed\n");
  30. }
  31. aos_pool_destroy(p);

注:

  • 因为文件元信息在上传/下载时是附在HTTP Headers中, HTTP协议规定不能包含复杂字符。
  • 一个文件可以有多个类似的参数,但所有的user meta总大小不能超过8KB。

获取文件的元数据

有时候,再向OSS上传文件后或者读取文件前需要获取文件的一些元数据,比如长度,文件类型等,这时候可以通过oss_object_head接口获取文件的元数据。下面代码获取文件的长度和文件类型:

  1. void head_object()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. oss_request_options_t *options = NULL;
  7. aos_table_t *headers = NULL;
  8. aos_table_t *resp_headers = NULL;
  9. aos_status_t *s = NULL;
  10. char *content_length_str = NULL;
  11. char *object_type = NULL;
  12. int64_t content_length = 0;
  13. aos_pool_create(&p, NULL);
  14. /* 创建并初始化options */
  15. options = oss_request_options_create(p);
  16. init_options(options);
  17. /* 初始化参数 */
  18. aos_str_set(&bucket, "<您的bucket名字>");
  19. aos_str_set(&object, "<您的object名字>");
  20. headers = aos_table_make(p, 0);
  21. /* 获取文件元数据 */
  22. s = oss_head_object(options, &bucket, &object, headers, &resp_headers);
  23. if (aos_status_is_ok(s)) {
  24. /* 获取文件长度 */
  25. content_length_str = (char*)apr_table_get(resp_headers, OSS_CONTENT_LENGTH);
  26. if (content_length_str != NULL) {
  27. content_length = atoll(content_length_str);
  28. }
  29. /* 获取文件的类型 */
  30. object_type = (char*)apr_table_get(resp_headers, OSS_OBJECT_TYPE);
  31. printf("head object succeeded, object type:%s, content_length:%ld\n",
  32. object_type, content_length);
  33. } else {
  34. printf("head object failed\n");
  35. }
  36. aos_pool_destroy(p);
  37. }

注:

  • oss_head_object接口不会去下载文件内容,只会读取文件的元数据,包括系统级别和用户自定义的元数据
  • 完整代码参考:GitHub

拷贝文件

在同一个region中,用户可以对有操作权限的文件进行拷贝操作。以下代码通过oss_copy_object接口实现拷贝一个文件:

  1. aos_pool_t *p;
  2. oss_request_options_t *options;
  3. aos_status_t *s;
  4. aos_table_t * headers;
  5. aos_table_t *resp_headers;
  6. char *source_bucket_name = "<您的源bucket名字>";
  7. char *source_object_name = "<您的源object名字>";
  8. char *dest_bucket_name = "<您的目的bucket名字>";
  9. char *dest_object_name = "<您的目的object名字>";
  10. aos_string_t source_bucket;
  11. aos_string_t source_object;
  12. aos_string_t dest_bucket;
  13. aos_string_t dest_object;
  14. aos_pool_create(&p, NULL);
  15. options = oss_request_options_create(p);
  16. init_options(options);
  17. aos_str_set(&source_bucket, source_bucket_name);
  18. aos_str_set(&source_object, source_object_name);
  19. aos_str_set(&dest_bucket, dest_bucket_name);
  20. aos_str_set(&dest_object, dest_object_name);
  21. headers = aos_table_make(p, 0);
  22. /* 拷贝文件 */
  23. s = oss_copy_object(options, &source_bucket, &source_object, &dest_bucket, &dest_object, headers, &resp_headers);
  24. if (aos_status_is_ok(s)) {
  25. printf("copy object succeeded\n");
  26. } else {
  27. printf("copy object failed\n");
  28. }
  29. aos_pool_destroy(p);

注:

  • 需要注意的是源bucket与目的bucket必须属于同一region。
  • 如果拷贝文件超过1G,建议使用分片拷贝文件方式进行拷贝。

分片拷贝文件

当拷贝一个大于500MB的文件,建议通过oss_upload_part_copy接口来进行拷贝。以下代码实现分片拷贝一个文件

  1. aos_pool_t *p;
  2. oss_request_options_t *options;
  3. char *source_bucket_name = "<您的源bucket名字>";
  4. char *source_object_name = "<您的源object名字>";
  5. char *dest_bucket_name = "<您的目的bucket名字>";
  6. char *dest_object_name = "<您的目的object名字>";
  7. aos_string_t dest_bucket;
  8. aos_string_t dest_object;
  9. aos_string_t upload_id;
  10. aos_table_t *init_headers;
  11. aos_table_t *copy_headers;
  12. aos_table_t *list_part_resp_headers;
  13. aos_table_t *complete_resp_headers
  14. aos_table_t *resp_headers;
  15. aos_status_t *s;
  16. oss_list_upload_part_params_t *list_upload_part_params;
  17. oss_upload_part_copy_params_t *upload_part_copy_params1;
  18. aos_list_t complete_part_list;
  19. oss_list_part_content_t *part_content;
  20. oss_complete_part_content_t *complete_content;
  21. int part1 = 1;
  22. int64_t range_start1 = 0;
  23. int64_t range_end1 = 6000000;//not less than 5MB
  24. int max_ret = 1000;
  25. aos_pool_create(&p, NULL);
  26. options = oss_request_options_create(p);
  27. init_options(options);
  28. aos_str_set(&dest_bucket, dest_bucket_name);
  29. aos_str_set(&dest_object, dest_object_name);
  30. init_headers = aos_table_make(p, 0);
  31. s = oss_init_multipart_upload(options, &dest_bucket, &dest_object, init_headers, &upload_id, &resp_headers);
  32. /* 拷贝第一个分片数据 */
  33. upload_part_copy_params1 = oss_create_upload_part_copy_params(p);
  34. aos_str_set(&upload_part_copy_params1->source_bucket, source_bucket_name);
  35. aos_str_set(&upload_part_copy_params1->source_object, source_object_name);
  36. aos_str_set(&upload_part_copy_params1->dest_bucket, dest_bucket_name);
  37. aos_str_set(&upload_part_copy_params1->dest_object, dest_object_name);
  38. aos_str_set(&upload_part_copy_params1->upload_id, upload_id->data);
  39. upload_part_copy_params1->part_num = part1;
  40. upload_part_copy_params1->range_start = range_start1;
  41. upload_part_copy_params1->range_end = range_end1;
  42. copy_headers = aos_table_make(p, 0);
  43. s = oss_upload_part_copy(options, upload_part_copy_params1, copy_headers, &resp_headers);
  44. if (aos_status_is_ok(s)) {
  45. printf("upload part copy succeeded\n");
  46. } else {
  47. printf("upload part copy failed\n");
  48. }
  49. /* 继续拷贝剩余的分片,这里省略*/
  50. /* 列出分片 */
  51. list_upload_part_params = oss_create_list_upload_part_params(p);
  52. list_upload_part_params->max_ret = max_ret;
  53. aos_list_init(&complete_part_list);
  54. s = oss_list_upload_part(options, &dest_bucket, &dest_object, &upload_id,
  55. list_upload_part_params, &list_part_resp_headers);
  56. aos_list_for_each_entry(part_content, &list_upload_part_params->part_list, node) {
  57. complete_content = oss_create_complete_part_content(p);
  58. aos_str_set(&complete_content->part_number, part_content->part_number.data);
  59. aos_str_set(&complete_content->etag, part_content->etag.data);
  60. aos_list_add_tail(&complete_content->node, &complete_part_list);
  61. }
  62. /* 完成分片拷贝 */
  63. s = oss_complete_multipart_upload(options, &dest_bucket, &dest_object, &upload_id, &complete_part_list, &complete_resp_headers);
  64. if (aos_status_is_ok(s)) {
  65. printf("complete multipart upload succeeded\n");
  66. } else {
  67. printf("complete multipart upload failed\n");
  68. }
  69. aos_pool_destroy(p);

删除文件

通过oss_delete_object接口,可以实现删除某个文件:

  1. void delete_object()
  2. {
  3. aos_pool_t *p = NULL;
  4. aos_string_t bucket;
  5. aos_string_t object;
  6. oss_request_options_t *options = NULL;
  7. aos_table_t *resp_headers = NULL;
  8. aos_status_t *s = NULL;
  9. aos_pool_create(&p, NULL);
  10. /* 创建并初始化options */
  11. options = oss_request_options_create(p);
  12. init_options(options);
  13. aos_str_set(&bucket, "<您的bucket名字>");
  14. aos_str_set(&object, "<您的object名字>");
  15. /* 删除文件 */
  16. s = oss_delete_object(options, &bucket, &object, &resp_headers);
  17. /* 判断是否删除成功 */
  18. if (aos_status_is_ok(s)) {
  19. printf("delete object succeed\n");
  20. } else {
  21. printf("delete object failed\n");
  22. }
  23. /* 释放资源*/
  24. aos_pool_destroy(p);
  25. }

注:

批量删除文件

通过oss_delete_objects接口,可以实现删除一批文件,用户可以通过is_quiet参数来指定是否返回删除的结果:

  1. aos_pool_t *p;
  2. aos_status_t *s;
  3. aos_table_t *resp_headers;
  4. oss_request_options_t *options;
  5. char *bucket_name = "<您的bucket名字>";
  6. char *object_name1 = "<您的object名字1>";
  7. char *object_name2 = "<您的object名字2>";
  8. aos_string_t bucket;
  9. aos_string_t object1;
  10. aos_string_t object2;
  11. oss_object_key_t *content1;
  12. oss_object_key_t *content2;
  13. aos_list_t object_list;
  14. aos_list_t deleted_object_list;
  15. int is_quiet = 1;
  16. options = oss_request_options_create(p);
  17. init_options(options);
  18. aos_str_set(&bucket, bucket_name);
  19. aos_str_set(&object1, object_name1);
  20. aos_str_set(&object2, object_name2);
  21. /* 构建待删除文件列表 */
  22. aos_list_init(&object_list);
  23. aos_list_init(&deleted_object_list);
  24. content1 = oss_create_oss_object_key(p);
  25. aos_str_set(&content1->key, object_name1);
  26. aos_list_add_tail(&content1->node, &object_list);
  27. content2 = oss_create_oss_object_key(p);
  28. aos_str_set(&content2->key, object_name2);
  29. aos_list_add_tail(&content2->node, &object_list);
  30. /* 删除多个文件 */
  31. s = oss_delete_objects(options, &bucket, &object_list, is_quiet, &resp_headers, &deleted_object_list);
  32. if (aos_status_is_ok(s)) {
  33. printf("delete objects succeeded\n");
  34. } else {
  35. printf("delete objects failed\n");
  36. }
  37. aos_pool_destroy(p);

批量删除指定前缀的文件

通过oss_delete_objects_by_prefix接口,可以实现删除一批指定前缀的文件:

  1. aos_pool_t *p;
  2. oss_request_options_t *options;
  3. aos_status_t *s;
  4. aos_table_t *resp_headers;
  5. char *bucket_name = "<您的bucket名字>";
  6. char *prefix_str = "<删除文件的前缀>";
  7. aos_string_t bucket;
  8. aos_string_t prefix;
  9. aos_pool_create(&p, NULL);
  10. options = oss_request_options_create(p);
  11. init_options(options);
  12. aos_str_set(&bucket, bucket_name);
  13. aos_str_set(&prefix, prefix_str);
  14. /* 删除满足特定前缀的文件*/
  15. s = oss_delete_objects_by_prefix(options, &bucket, &prefix);
  16. if (aos_status_is_ok(s)) {
  17. printf("delete objects by prefix succeeded\n");
  18. } else {
  19. printf("delete objects by prefix failed\n");
  20. }
  21. aos_pool_destroy(p);

注:

  • 批量删除指定前缀的文件可以实现删除目录的功能,比如删除dir目录,可以通过设置prefix的值为 dir/ 实现。
  • 如果设置prefix的值为空字符串(“”)或者NULL,将会删除整个bucket,请谨慎使用。
本文导读目录
本文导读目录
以上内容是否对您有帮助?