Object

上传Object

最简单的上传

  • 基本流程

    1. 创建BOSClient类的实例。
    2. 调用BOSClient putObject方法,可以通过如下二种方式上传Object:文件、二进制数据的形式。
    3. 对返回的BOSPutObjectResponse类型实例,可以执行获取eTag操作。
  • 示例代码

    BOSObjectContent* content = [[BOSObjectContent alloc] init];
    // 以文件方式
    content.objectData.file = @"<file path>";
    
    // 或者以二进制数据方式
    NSData* data = [[NSData alloc] init];
    content.objectData.data = data;
    
    BOSPutObjectRequest* request = [[BOSPutObjectRequest alloc] init];
    request.bucket = @"<bucketname>";
    request.key = @"<objectname>";
    request.objectContent = content;
    
    __block BOSPutObjectResponse* response = nil;
    BCETask* task = [client putObject:request];
    task.then(^(BCEOutput* output) {
      if (output.progress) {
          NSLog(@"put object progress is %@", output.progress);
      }
    
      if (output.response) {
          response = (BOSPutObjectResponse*)output.response;
          NSLog(@"put object success!");
      }
    
      if (output.error) {
          NSLog(@"put object failure");
      }
    });
    [task waitUtilFinished];
    

    说明:Object以文件的形式上传到BOS中,putObject函数支持不超过5GB的Object上传。在putObject请求处理成功后,BOS会在Header中返回Object的ETag作为文件标识。

  • 完整示例

    #import <BaiduBCEBasic/BaiduBCEBasic.h>
    #import <BaiduBCEBOS/BaiduBCEBOS.h>
    
    void example(void) {
    // 初始化
    BCECredentials* credentials = [[BCECredentials alloc] init];
    credentials.accessKey = @"<access key>";
    credentials.secretKey = @"<secret key>";
    BOSClientConfiguration* configuration = [[BOSClientConfiguration alloc] init];
    configuration.credentials = credentials;
    
    BOSClient* client = [[BOSClient alloc] initWithConfiguration:configuration];
    
    BOSObjectContent* content = [[BOSObjectContent alloc] init];
    // 以文件方式
    content.objectData.file = @"<file path>";
    
    // 或者以二进制数据方式
    NSData* data = [[NSData alloc] init];
    content.objectData.data = data;
    
    BOSPutObjectRequest* request = [[BOSPutObjectRequest alloc] init];
    request.bucket = @"<bucketname>";
    request.key = @"<objectname>";
    request.objectContent = content;
    
    __block BOSPutObjectResponse* response = nil;
    BCETask* task = [client putObject:request];
    task.then(^(BCEOutput* output) {
        if (output.progress) {
            NSLog(@"put object progress is %@", output.progress);
        }
    
        if (output.response) {
            response = (BOSPutObjectResponse*)output.response;
            NSLog(@"put object success!");
        }
    
        if (output.error) {
            NSLog(@"put object failure");
        }
    });
    [task waitUtilFinished];
    }
    

设定Object的Http Header

BOS支持您在上传object时设定Http Header。

  • 基本流程

    1. 创建BOSObjectMetadata类的实例。
    2. 设定BOSObjectMetadata实例的contentEncoding/contentType/contentDisposition等字段。
    3. 将BOSObjectMetadata实例设置到BOSPutObjectRequest的objectContent.metadata字段上。
  • 示例代码

    BOSObjectMetadata* metadata = [[BOSObjectMetadata alloc] init];
    metadata.contentEncoding = @"<encoding>";
    metadata.contentDisposition = @"<content disposition>";
    content.metadata = metadata;
    
  • 完整示例

    #import <BaiduBCEBasic/BaiduBCEBasic.h>
    #import <BaiduBCEBOS/BaiduBCEBOS.h>
    
    void example(void) {
    // 初始化
    BCECredentials* credentials = [[BCECredentials alloc] init];
    credentials.accessKey = @"<access key>";
    credentials.secretKey = @"<secret key>";
    BOSClientConfiguration* configuration = [[BOSClientConfiguration alloc] init];
    configuration.credentials = credentials;
    
    BOSClient* client = [[BOSClient alloc] initWithConfiguration:configuration];
    
    BOSObjectContent* content = [[BOSObjectContent alloc] init];
    // 以文件方式
    content.objectData.file = @"<file path>";
    
    // 或者以二进制数据方式
    NSData* data = [[NSData alloc] init];
    content.objectData.data = data;
    
    BOSObjectMetadata* metadata = [[BOSObjectMetadata alloc] init];
    metadata.contentEncoding = @"<encoding>";
    metadata.contentDisposition = @"<content disposition>";
    content.metadata = metadata;
    
    BOSPutObjectRequest* request = [[BOSPutObjectRequest alloc] init];
    request.bucket = @"<bucketname>";
    request.key = @"<Objectname>";
    request.objectContent = content;
    
    __block BOSPutObjectResponse* response = nil;
    BCETask* task = [client putObject:request];
    task.then(^(BCEOutput* output) {
        if (output.progress) {
            NSLog(@"put object progress is %@", output.progress);
        }
    
        if (output.response) {
            response = (BOSPutObjectResponse*)output.response;
            NSLog(@"put object success!");
        }
    
        if (output.error) {
            NSLog(@"put object failure");
        }
    });
    [task waitUtilFinished];
    }
    

用户自定义元数据

BOS支持用户自定义元数据来对Object进行描述。

  • 基本流程

    1. 创建BOSObjectMetadata类的实例。
    2. 将自定义元数据字典设置到BOSObjectMetadata的userMetadata字段。
  • 示例代码

    BOSObjectMetadata* metadata = [[BOSObjectMetadata alloc] init];
    metadata.contentEncoding = @"<encoding>";
    metadata.contentDisposition = @"<content disposition>";
    content.metadata = metadata;
    
    NSDictionary* customMetadata = @{
      @"name" : @"my-data"
    };
    content.metadata.userMetadata = customMetadata;
    

    说明:在上面代码中,用户自定义了一个名字为”name”,值为”my-data”的元数据。当用户下载此Object的时候,此元数据也可以一并得到。一个Object可以有多个类似的参数,但所有的User Meta总大小不能超过2KB。

  • 完整示例

    #import <BaiduBCEBasic/BaiduBCEBasic.h>
    #import <BaiduBCEBOS/BaiduBCEBOS.h>
    
    void example(void) {
    // 初始化
    BCECredentials* credentials = [[BCECredentials alloc] init];
    credentials.accessKey = @"<access key>";
    credentials.secretKey = @"<secret key>";
    BOSClientConfiguration* configuration = [[BOSClientConfiguration alloc] init];
    configuration.credentials = credentials;
    
    BOSClient* client = [[BOSClient alloc] initWithConfiguration:configuration];
    
    BOSObjectContent* content = [[BOSObjectContent alloc] init];
    // 以文件方式
    content.objectData.file = @"<file path>";
    
    // 或者以二进制数据方式
    NSData* data = [[NSData alloc] init];
    content.objectData.data = data;
    
    BOSObjectMetadata* metadata = [[BOSObjectMetadata alloc] init];
    metadata.contentEncoding = @"<encoding>";
    metadata.contentDisposition = @"<content disposition>";
    content.metadata = metadata;
    
    NSDictionary* customMetadata = @{
        @"name" : @"my-data"
    };
    content.metadata.userMetadata = customMetadata;
    
    BOSPutObjectRequest* request = [[BOSPutObjectRequest alloc] init];
    request.bucket = @"<bucketname>";
    request.key = @"<objectname>";
    request.objectContent = content;
    
    __block BOSPutObjectResponse* response = nil;
    BCETask* task = [client putObject:request];
    task.then(^(BCEOutput* output) {
        if (output.progress) {
            NSLog(@"put object progress is %@", output.progress);
        }
    
        if (output.response) {
            response = (BOSPutObjectResponse*)output.response;
            NSLog(@"put object success!");
        }
    
        if (output.error) {
            NSLog(@"put object failure");
        }
    });
    [task waitUtilFinished];
    }
    

查看Bucket中的Object

简单查询

查看Bucket中Object列表。

  • 基本流程

    1. 创建BOSClient类的实例。
    2. 执行BOSClient listObjects方法,会返回BOSListObjectsResponse类的实例。
    3. 可以对BOSListObjectsResponse类型的contents字段进行枚举,获取key/lastModified/eTag/size/owner。
  • 示例代码

    BOSListObjectsRequest* listObjRequest = [[BOSListObjectsRequest alloc] init];
    listObjRequest.bucket = @"<bucketname>";
    
    __block BOSListObjectsResponse* listObjResponse = nil;
    BCETask* task = [client listObjects:listObjRequest];
    task.then(^(BCEOutput* output) {
      if (output.response) {
          listObjResponse = (BOSListObjectsResponse*)output.response;
    
          for (BOSObjectInfo* object in listObjResponse.contents) {
              NSLog(@"the object key is %@", object.key);
              NSLog(@"the object lastModified is %@", object.lastModified);
              NSLog(@"the object eTag is %@", object.eTag);
              NSLog(@"the object size is %llu", object.size);
              NSLog(@"the object owner id is %@", object.owner.ownerID);
          }
      }
    
      if (output.error) {
          NSLog(@"list objects failure");
      }
    });
    [task waitUtilFinished];
    

    说明: listObjects方法返回BOSListObjectsResponse对象,BOSListObjectsResponse对象包含了此次listObject请求的返回结果。用户可以通过BOSListObjectsResponse中的contents属性获取所有Object的描述信息。

    • 默认情况下,如果Bucket中的Object数量大于1000,则只会返回1000个Object,并且返回结果中isTruncated值为YES,并返回nextMarker做为下次读取的起点。
    • 若想获取更多的Object,可以使用marker参数分次读取,请参考扩展查询
  • 完整示例

    #import <BaiduBCEBasic/BaiduBCEBasic.h>
    #import <BaiduBCEBOS/BaiduBCEBOS.h>
    
    void example(void) {
    // 初始化
    BCECredentials* credentials = [[BCECredentials alloc] init];
    credentials.accessKey = @"<access key>";
    credentials.secretKey = @"<secret key>";
    BOSClientConfiguration* configuration = [[BOSClientConfiguration alloc] init];
    configuration.credentials = credentials;
    
    BOSClient* client = [[BOSClient alloc] initWithConfiguration:configuration];
    
    BOSListObjectsRequest* listObjRequest = [[BOSListObjectsRequest alloc] init];
    listObjRequest.bucket = @"<bucketname>";
    
    __block BOSListObjectsResponse* listObjResponse = nil;
    BCETask* task = [client listObjects:listObjRequest];
    task.then(^(BCEOutput* output) {
        if (output.response) {
            listObjResponse = (BOSListObjectsResponse*)output.response;
    
            for (BOSObjectInfo* object in listObjResponse.contents) {
                NSLog(@"the object key is %@", object.key);
                NSLog(@"the object lastModified is %@", object.lastModified);
                NSLog(@"the object eTag is %@", object.eTag);
                NSLog(@"the object size is %llu", object.size);
                NSLog(@"the object owner id is %@", object.owner.ownerID);
            }
        }
    
        if (output.error) {
            NSLog(@"list objects failure");
        }
    });
    [task waitUtilFinished];
    }
    

扩展查询

用户可以通过设置BOSListObjectsResquest参数来完成更多扩展查询操作设置。BOSListObjectsResquest中可以设置的扩展参数如下:

参数名称 说明 默认值
maxKeys 设定此次返回Object的最大个数,不可超过1000。 1000
prefix 设定objectKey的前缀,前缀是指objectKey包含并以prefix的值作为开始。通常与delimiter配合在查询模拟文件夹中使用。 -
delimiter 是一个分隔符,用来对objectKey进行分层。通常与prefix配合在查询模拟文件夹中使用。从prefix开始到第一次出现delimiter字符之间的objectKey称为:commonPrefixes。 -
marker 是一个字符串,用来设定返回结果的起始位置。设定marker值之后,返回的Object会从marker值之后按字母排序开始返回。 -
  • 基本流程

    1. 创建BOSListObjectsResquest类的实例。
    2. 设置BOSListObjectsResquest的delimiter/marker/prefix/maxKeys等字段,实现更多的扩展查询操作。
    3. 创建BOSClient类的实例,执行listObjects。
  • 示例代码

    BOSListObjectsRequest* listObjRequest = [[BOSListObjectsRequest alloc] init];
    listObjRequest.bucket = @"<bucketname>";
    listObjRequest.marker = @"<marker>";
    
    __block BOSListObjectsResponse* listObjResponse = nil;
    BCETask* task = [client listObjects:listObjRequest];
    task.then(^(BCEOutput* output) {
      if (output.response) {
          listObjResponse = (BOSListObjectsResponse*)output.response;
    
          for (BOSObjectInfo* object in listObjResponse.contents) {
              NSLog(@"the object key is %@", object.key);
              NSLog(@"the object lastModified is %@", object.lastModified);
              NSLog(@"the object eTag is %@", object.eTag);
              NSLog(@"the object size is %llu", object.size);
              NSLog(@"the object owner id is %@", object.owner.ownerID);
          }
      }
    
      if (output.error) {
          NSLog(@"list objects failure");
      }
    });
    [task waitUtilFinished];
    
  • 完整示例

    示例一:

    #import <BaiduBCEBasic/BaiduBCEBasic.h>
    #import <BaiduBCEBOS/BaiduBCEBOS.h>
    
    void example(void) {
    // 初始化
    BCECredentials* credentials = [[BCECredentials alloc] init];
    credentials.accessKey = @"<access key>";
    credentials.secretKey = @"<secret key>";
    BOSClientConfiguration* configuration = [[BOSClientConfiguration alloc] init];
    configuration.credentials = credentials;
    
    BOSClient* client = [[BOSClient alloc] initWithConfiguration:configuration];
    
    BOSListObjectsRequest* listObjRequest = [[BOSListObjectsRequest alloc] init];
    listObjRequest.bucket = @"<bucketname>";
    listObjRequest.marker = @"<marker>";
    
    __block BOSListObjectsResponse* listObjResponse = nil;
    BCETask* task = [client listObjects:listObjRequest];
    task.then(^(BCEOutput* output) {
        if (output.response) {
            listObjResponse = (BOSListObjectsResponse*)output.response;
    
            for (BOSObjectInfo* object in listObjResponse.contents) {
                NSLog(@"the object key is %@", object.key);
                NSLog(@"the object lastModified is %@", object.lastModified);
                NSLog(@"the object eTag is %@", object.eTag);
                NSLog(@"the object size is %llu", object.size);
                NSLog(@"the object owner id is %@", object.owner.ownerID);
            }
        }
    
        if (output.error) {
            NSLog(@"list objects failure");
        }
    });
    [task waitUtilFinished];
    }
    

    示例二:使用nextMarker的完整示例。

    #import <BaiduBCEBasic/BaiduBCEBasic.h>
    #import <BaiduBCEBOS/BaiduBCEBOS.h>
    
    void example(void) {
    // 初始化
    BCECredentials* credentials = [[BCECredentials alloc] init];
    credentials.accessKey = @"<access key>";
    credentials.secretKey = @"<secret key>";
    BOSClientConfiguration* configuration = [[BOSClientConfiguration alloc] init];
    configuration.credentials = credentials;
    
    BOSClient* client = [[BOSClient alloc] initWithConfiguration:configuration];
    
    BOSListObjectsRequest* listObjRequest = [[BOSListObjectsRequest alloc] init];
    listObjRequest.bucket = @"<bucketname>";
    listObjRequest.marker = @"<marker>";
    
    __block BOSListObjectsResponse* listObjResponse = nil;
    BCETask* task = [client listObjects:listObjRequest];
    task.then(^(BCEOutput* output) {
        if (output.response) {
            listObjResponse = (BOSListObjectsResponse*)output.response;
        }
    
        if (output.error) {
            NSLog(@"list objects failure");
        }
    });
    [task waitUtilFinished];
    
    if (listObjResponse != nil) {
        listObjRequest.marker = listObjResponse.nextMarker;
        task = [client listObjects:listObjRequest];
        task.then(^(BCEOutput* output) {
            if (output.response) {
                listObjResponse = (BOSListObjectsResponse*)output.response;
    
                for (BOSObjectInfo* object in listObjResponse.contents) {
                    NSLog(@"the object key is %@", object.key);
                    NSLog(@"the object lastModified is %@", object.lastModified);
                    NSLog(@"the object eTag is %@", object.eTag);
                    NSLog(@"the object size is %llu", object.size);
                    NSLog(@"the object owner id is %@", object.owner.ownerID);
                }
            }
        });
    }
    }
    

查询模拟文件夹

由于BOS本身是一个(<Key>,<Value>)的存储系统,所以原则上并不会存在“文件夹”的概念,但您可以通过delimiterprefix参数的配合进行文件夹功能模拟。

假设Bucket中有5个文件:bos.jpg,fun/,fun/test.jpg,fun/movie/001.avi,fun/movie/007.avi,可以把 “/” 符号作为分隔符模拟文件夹。

递归列出模拟文件夹下所有文件

可以通过设置prefix参数来获取某个模拟文件夹下所有的文件:

BOSListObjectsRequest* listObjRequest = [[BOSListObjectsRequest alloc] init];
listObjRequest.bucket = @"<bucketname>";
 listObjRequest.prefix = @"fun/";

__block BOSListObjectsResponse* listObjResponse = nil;
BCETask* task = [client listObjects:listObjRequest];
task.then(^(BCEOutput* output) {
    if (output.response) {
        listObjResponse = (BOSListObjectsResponse*)output.response;

        for (BOSObjectInfo* object in listObjResponse.contents) {
            NSLog(@"%@", object.key);
        }
    }
});
[task waitUtilFinished];

输出:

Objects:
fun/
fun/movie/001.avi
fun/movie/007.avi
fun/test.jpg

查看模拟文件夹下的文件和子文件夹

prefixdelimiter结合的情况下,可以列出模拟文件夹下的文件和子文件夹:

BOSListObjectsRequest* listObjRequest = [[BOSListObjectsRequest alloc] init];
listObjRequest.bucket = @"<bucketname>";

// 指定"/"为模拟文件夹的分隔符
listObjRequest.delimiter = @"/";

// 列出fun文件夹下的所有文件和子文件夹
listObjRequest.prefix = @"fun/";

__block BOSListObjectsResponse* listObjResponse = nil;
BCETask* task = [client listObjects:listObjRequest];
task.then(^(BCEOutput* output) {
    if (output.response) {
        listObjResponse = (BOSListObjectsResponse*)output.response;
    }

    if (output.error) {
        NSLog(@"list objects failure");
    }
});
[task waitUtilFinished];

// 遍历所有Object
NSLog(@"Objects:");
for (BOSObjectInfo* object in listObjResponse.contents) {
    NSLog(@"%@", object.key);
}

// 遍历所有CommonPrefix
NSLog(@"CommonPrefixs:");
for (NSString* commonPrefix in listObjResponse.commonPrefixes) {
    NSLog(@"%@", commonPrefix);
}

输出:

Objects:
fun/
fun/test.jpg

CommonPrefixs:
fun/movie/

说明: 返回的结果中,contents的列表中给出的是fun文件夹下的文件。而commonPrefixs的列表中给出的是fun文件夹下的所有子文件夹。可以看出fun/movie/001.avifun/movie/007.avi两个文件并没有被列出来,因为它们属于fun文件夹下的movie子文件夹下的文件。

获取Object

简单的获取Object

用户可以通过如下代码将Object读取到内存中。

  • 基本流程

    1. 创建BOSClient类的实例。
    2. 执行BOSClient getObject方法,会返回BOSGetObjectResponse实例。
    3. 访问BOSGetObjectResponse示例的objectContent.objectData.data属性,获取数据。