Object管理
所有文档

          对象存储 BOS

          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属性,获取数据。
          • 示例代码

            __block BOSGetObjectResponse* getObjResponse = nil;
            BOSGetObjectRequest* getObjRequest = [[BOSGetObjectRequest alloc] init];
            getObjRequest.bucket = @"<bucketname>";
            getObjRequest.key = @"<objectname>";
            BCETask* task = [client getObject:getObjRequest];
            task.then(^(BCEOutput* output) {
              if (output.response) {
                  getObjResponse = (BOSGetObjectResponse*)output.response;
                  NSLog(@"get object success!");
              }
            
              if (output.error) {
                  NSLog(@"get object failure with %@", outpu****t.error);
              }
            
              if (output.progress) {
                  NSLog(@"the get object progress is %@", output.progress);
              }
            });
            [task waitUtilFinished];
            
            // 获取内存中的数据
            NSData* data = getObjResponse.objectContent.objectData.data;

            注意:

            • BOSObjectContent中包含了Object的各种信息,包含Object所在的Bucket、Object的名称、MetaData以及数据存储。
            • BOSObjectMetadata中包含了Object上传时定义的ETag,Http Header以及自定义的元数据。
            • 通过BOSObjectContent的objectData属性,获取到Object的数据。
          • 完整示例

            #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];
            
                __block BOSGetObjectResponse* getObjResponse = nil;
                BOSGetObjectRequest* getObjRequest = [[BOSGetObjectRequest alloc] init];
                getObjRequest.bucket = @"<bucketname>";
                getObjRequest.key = @"<objectname>";
                BCETask* task = [client getObject:getObjRequest];
                task.then(^(BCEOutput* output) {
                    if (output.response) {
                        getObjResponse = (BOSGetObjectResponse*)output.response;
                        NSLog(@"get object success!");
                    }
            
                    if (output.error) {
                        NSLog(@"get object failure with %@", output.error);
                    }
            
                    if (output.progress) {
                        NSLog(@"the get object progress is %@", output.progress);
                    }
                });
                [task waitUtilFinished];
            
                NSData* data = getObjResponse.objectContent.objectData.data;
            }

          下载Object的一部分内容

          • 基本流程

            1. 创建BOSGetObjectRequest类的实例。
            2. BOSGetObjectRequestt实例的rangeStart和/或rangeEnd字段。
            3. 执行client getObject操作。
          • 示例代码

            __block BOSGetObjectResponse* getObjResponse = nil;
            BOSGetObjectRequest* getObjRequest = [[BOSGetObjectRequest alloc] init];
            getObjRequest.bucket = @"<bucketname>";
            getObjRequest.key = @"<objectname>";
            
            // 获取前100个字节
            getObjRequest.rangeStart = @"0";
            getObjRequest.rangeStart = @"99";
            
            BCETask* task = [client getObject:getObjRequest];
            task.then(^(BCEOutput* output) {
                if (output.response) {
                    getObjResponse = (BOSGetObjectResponse*)output.response;
                    NSLog(@"get object success!");
                }
            
                if (output.error) {
                    NSLog(@"get object failure with %@", output.error);
                }
            
                if (output.progress) {
                    NSLog(@"the get object progress is %@", output.progress);
                }
            });
            [task waitUtilFinished];
            
            NSData* data = getObjResponse.objectContent.objectData.data;

            说明:用户可以用此功能实现文件的分段下载和断点续传。

          下载Object到指定路径

          用户可以通过如下代码直接将Object下载到指定路径。

          • 基本流程

            1. 创建BOSGetObjectRequest类的实例。
            2. 设置要保存的文件名到BOSGetObjectRequest实例的file字段。
            3. 执行client getObject操作。
            4. Object可以直接下载到指定路径。
          • 示例代码

            __block BOSGetObjectResponse* getObjResponse = nil;
            BOSGetObjectRequest* getObjRequest = [[BOSGetObjectRequest alloc] init];
            getObjRequest.bucket = @"<bucketname>";
            getObjRequest.key = @"<objectname>";
            
            // 设置保存到的文件路径
            getObjRequest.file = @"<file>";
            
            BCETask* task = [client getObject:getObjRequest];
            task.then(^(BCEOutput* output) {
                if (output.response) {
                    getObjResponse = (BOSGetObjectResponse*)output.response;
                    NSLog(@"get object success!");
                }
            
                if (output.error) {
                    NSLog(@"get object failure with %@", output.error);
                }
            
                if (output.progress) {
                    NSLog(@"the get object progress is %@", output.progress);
                }
            });
            [task waitUtilFinished];

          获取Object的storageClass

          Object的storage class属性分为STANDARD(标准存储), STANDARD_IA(低频存储)和COLD(冷存储)。

          示例代码

          __block BOSGetObjectMetadataResponse* getObjMetaResponse = nil;
          BCETask* task = [client getObjectMetadata:@"<bucketname>" objectKey:@"<objectname>"];
          task.then(^(BCEOutput* output) {
              if (output.response) {
                  getObjMetaResponse = (BOSGetObjectMetadataResponse*)output.response;
                  NSString storageClass = getObjMetaResponse.storageClass;
                  NSLog(@"get object storageClass success!");
              }
          
              if (output.error) {
                  NSLog(@"get object storageClass failure");
              }
          });
          [task waitUtilFinished];

          只获取ObjectMetadata

          通过getObjectMetadata 方法可以只获取 Object metadata 而不获取Object的实体。

          • 示例代码

            __block BOSGetObjectMetadataResponse* getObjMetaResponse = nil;
            BCETask* task = [client getObjectMetadata:@"<bucketname>" objectKey:@"<objectname>"];
            task.then(^(BCEOutput* output) {
                if (output.response) {
                    getObjMetaResponse = (BOSGetObjectMetadataResponse*)output.response;
                    NSLog(@"get object metadata success!");
                }
            
                if (output.error) {
                    NSLog(@"get object metadata failure");
                }
            });
            [task waitUtilFinished];

          获取Object的URL

          您可以通过如下代码获取指定Object的URL,该功能通常用于您将Object的URL临时分享给其他用户的场景。

          • 基本流程

            1. 创建BOSClient类的实例。
            2. 执行BOSClient generatePresignedUrl方法。
            3. 返回一个Object的URL。
          • 示例代码

            __block BOSGeneratePresignedUrlResponse *generateObjetUrlRes = nil;
              BCEOutput_ output = [client generatePresignedUrl:@"<bucketname>" objectKey:@"<objectname>" expirationInSeconds:<ExpirationInSeconds>];
              if (output.response) {
                  generateObjetUrlRes = (BOSGeneratePresignedUrlResponse_)output.response;
                  NSLog(@"get url success, the usrlstting is : %@", [generateObjetUrlRes.objectUrl absoluteString]);
              }
              if (output.error) {
                  NSLog(@"get url failure, error : %@:", output.error);
              }

          说明: ExpirationInSeconds为指定的URL有效时长,时间从当前时间算起,为可选参数,不配置时系统默认值为1800秒。如果要设置为永久不失效的时间,可以将ExpirationInSeconds参数设置为 -1,不可设置为其他负数。

          • 完整示例

            #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];
            
                __block BOSGeneratePresignedUrlResponse *generateObjetUrlRes = nil;
                  BCEOutput* output = [client generatePresignedUrl:@"<bucketname>" objectKey:@"<objectname>" expirationInSeconds:<ExpirationInSeconds>];
                if (output.response) {
                generateObjetUrlRes = 	(BOSGeneratePresignedUrlResponse*)output.response;
                NSLog(@"get url success, the usrlstting is : %@", [generateObjetUrlRes.objectUrl absoluteString]);
                }
                if (output.error) {
                NSLog(@"get url failure, error : %@:", output.error);
                }
            }

          删除Object

          • 基本流程

            1. 创建BOSClient类的实例。
            2. 执行BOSClient deleteObject方法。
            3. 若操作失败后产生错误。
          • 示例代码

            __block BOSDeleteObjectResponse* response = nil;
            BCETask* task = [client deleteObject:@"<bucketname>" objectKey:@"<objectname>"];
            task.then(^(BCEOutput* output) {
                if (output.response) {
                    response = (BOSDeleteObjectResponse*)output.response;
                    NSLog(@"delete obj success!");
                }
            
                if (output.error) {
                    NSLog(@"delete obj 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];
            
                __block BOSDeleteObjectResponse* response = nil;
                BCETask* task = [client deleteObject:@"<bucketname>" objectKey:@"<objectname>"];
                task.then(^(BCEOutput* output) {
                  if (output.response) {
                      response = (BOSDeleteObjectResponse*)output.response;
                      NSLog(@"delete obj success!");
                  }
            
                  if (output.error) {
                      NSLog(@"delete obj failure");
                  }
                });
                [task waitUtilFinished];
            }

          拷贝Object

          简单拷贝Object

          • 基本流程

            1. 创建BOSClient类的实例。
            2. 执行BOSClient copyObject方法。
            3. 返回BOSCopyObjectResponse类实例,可通过eTag/lastModified等属性获取eTag和最后修改时间。
          • 示例代码

            BOSCopyObjectRequest* request = [[BOSCopyObjectRequest alloc] init];
            request.bucket = @"<bucketname>";
            request.key = @"<objectname>";
            request.source = @"<sourceBucket>/<sourceObject";
            
            __block BOSCopyObjectResponse* response = nil;
            BCETask* task = [client copyObject:request];
            task.then(^(BCEOutput* output) {
                if (output.response) {
                    response = (BOSCopyObjectResponse*)output.response;
                    NSLog(@"copy obj success!");
                }
            
                if (output.error) {
                    NSLog(@"copy obj 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];
            
                BOSCopyObjectRequest* request = [[BOSCopyObjectRequest alloc] init];
                request.bucket = @"<bucketname>";
                request.key = @"<objectname>";
                request.source = @"<sourceBucket>/<sourceObject";
            
                __block BOSCopyObjectResponse* response = nil;
                BCETask* task = [client copyObject:request];
                task.then(^(BCEOutput* output) {
                  if (output.response) {
                      response = (BOSCopyObjectResponse*)output.response;
                      NSLog(@"copy obj success!");
                  }
            
                  if (output.error) {
                      NSLog(@"copy obj failure");
                  }
                });
                [task waitUtilFinished];
            }

            说明:copyObject 方法返回一个 BOSCopyObjectResponse 对象,该对象中包含了新Object的ETag和修改时间。

          指定条件拷贝Object

          您也可以通过指定条件来实现Object的拷贝。该功能一般用于如下场景:

          • Copy一个Object但重新设置meta。
          • 重置某个现有Object的meta(把源和目标设置为同一个Object)。
          • 当源Object的eTag与指定的eTag相同时复制;
          • 当源Object的eTag与指定的eTag不相同时复制;
          • 当源Object的在指定的时间后没有被修改时复制;
          • 当源Object的在指定的时间后被修改过时复制;

          具体内容如下:

          • 基本流程

            1. 创建BOSCopyObjectRequest类的实例,传入<source>,<ifMatchEtag>, <ifNotMatchEtag>,<ifModifiedSince>,<ifUnmodifiedSince>, <metadataDirective>参数。
            2. 返回BOSCopyObjectResponse类实例,可通过eTag/lastModified属性获取eTag和最后修改时间。
          • 示例代码

            BOSCopyObjectRequest* request = [[BOSCopyObjectRequest alloc] init];
            request.bucket = @"<bucketname>";
            request.key = @"<objectname>";
            request.source = @"<sourceBucket>/<sourceObject";
            request.metadataDirective = @"replace";
            request.ifModifiedSince = @"Wed, 01 Mar 2006 12:00:00 GMT";
            
            __block BOSCopyObjectResponse* response = nil;
            BCETask* task = [client copyObject:request];
            task.then(^(BCEOutput* output) {
              if (output.response) {
                  response = (BOSCopyObjectResponse*)output.response;
                  NSLog(@"copy obj success!");
              }
            
              if (output.error) {
                  NSLog(@"copy obj failure");
              }
            });
            [task waitUtilFinished];

            说明:BOSCopyObjectRequest 允许用户修改目的Object的ObjectMeta,同时也提供 MatchingETagConstraints 参数的设定。

          Object的分块上传

          除了通过putObject()方法上传文件到BOS以外,BOS还提供了另外一种上传模式:分块上传(Multipart Upload)。用户可以在如下的应用场景内(但不仅限于此),使用分块上传模式,如:

          • 需要支持断点上传。
          • 上传超过5GB大小的文件。
          • 网络条件较差,和BOS的服务器之间的连接经常断开。
          • 需要流式地上传文件。
          • 上传文件之前,无法确定上传文件的大小。

          分块完成Multipart Upload

          假设有一个文件,本地路径为/path/to/file.zip,由于文件比较大,使用分块上传其传输到BOS中。

          • 基本流程

            1. 初始化Multipart Upload。
            2. 上传分块。
            3. 完成分块上传。

          初始化Multipart Upload

          使用initiateMultipartUpload方法来初始化一个分块上传事件:

          • 示例代码

            BOSInitiateMultipartUploadRequest* initMPRequest = [[BOSInitiateMultipartUploadRequest alloc] init];
            initMPRequest.bucket = @"<bucketname>";
            initMPRequest.key = @"<objectname>";
            initMPRequest.contentType = @"<content type>";
            
            __block BOSInitiateMultipartUploadResponse* initMPResponse = nil;
            BCETask* task = [client initiateMultipartUpload:initMPRequest];
            task.then(^(BCEOutput* output) {
              if (output.response) {
                  initMPResponse = (BOSInitiateMultipartUploadResponse*)output.response;
                  NSLog(@"initiate multipart upload success!");
              }
            
              if (output.error) {
                  NSLog(@"initiate multipart upload failure");
              }
            });
            [task waitUtilFinished];
            
            NSString* uploadID = initMPResponse.uploadId;

            说明:initiateMultipartUpload的返回结果中含有uploadId,它是区分分块上传事件的唯一标识,在后面的操作中,我们将用到它。

          上传分块

          将文件分块上传。

          • 示例代码

            // 计算分块个数
            NSString* file = @"/path/to/file.zip";
            NSDictionary<NSString*, id>* attr = [[NSFileManager defaultManager] attributesOfItemAtPath:file error:nil];
            uint64_t fileSize = attr.fileSize;
            uint64_t partSize = 1024 * 1024 * 5L;
            uint64_t partCount = fileSize / partSize;
            if (fileSize % partSize != 0) {
              ++partCount;
            }
            
            NSMutableArray<BOSPart*>* parts = [NSMutableArray array];
            NSFileHandle* handle = [NSFileHandle fileHandleForReadingAtPath:@"/path/to/file.zip"];
            for (uint64_t i = 0; i < partCount; ++i) {
              // seek
              uint64_t skip = partSize * i;
              [handle seekToFileOffset:skip];
              uint64_t size = (partSize < fileSize - skip) ? partSize : fileSize - skip;
            
              // data
              NSData* data = [handle readDataOfLength:size];
            
              // request
              BOSUploadPartRequest* uploadPartRequest = [[BOSUploadPartRequest alloc] init];
              uploadPartRequest.bucket = @"<bucketname>";
              uploadPartRequest.key = @"<objectname>";
              uploadPartRequest.objectData.data = data;
              uploadPartRequest.partNumber = i + 1;
              uploadPartRequest.uploadId = uploadID;
            
              __block BOSUploadPartResponse* uploadPartResponse = nil;
              task = [client uploadPart:uploadPartRequest];
              task.then(^(BCEOutput* output) {
                  if (output.response) {
                      uploadPartResponse = (BOSUploadPartResponse*)output.response;
                      BOSPart* part = [[BOSPart alloc] init];
                      part.partNumber = i + 1;
                      part.eTag = uploadPartResponse.eTag;
                              [parts addObject:part];
                  }
              });
              [task waitUtilFinished];
            }

            注意:上面代码的核心是调用uploadPart方法来上传每一个分块,但是要注意以下几点:

            • uploadPart方法要求除最后一个Part以外,其他的Part大小都要大于等于5MB。但是Upload Part接口并不会立即校验上传Part的大小;只有当Complete Multipart Upload的时候才会校验。
            • 为了保证数据在网络传输过程中不出现错误,建议您在uploadPart后,使用每个分块BOS返回的Content-MD5值分别验证已上传分块数据的正确性。当所有分块数据合成一个Object后,不再含MD5值。
            • Part号码的范围是1~10000。如果超出这个范围,BOS将返回InvalidArgument的错误码。
            • 每次上传Part时都要把流定位到此次上传块开头所对应的位置。
            • 每次上传Part之后,BOS的返回结果会包含一个BOSPart对象,它是上传块的ETag与块编号(PartNumber)的组合,在后续完成分块上传的步骤中会用到它,因此需要将其保存起来。一般来讲这些BOSPart对象将被保存到数组中。

          完成分块上传

          • 示例代码

            BOSCompleteMultipartUploadRequest* compMultipartRequest = [[BOSCompleteMultipartUploadRequest alloc] init];
            compMultipartRequest.bucket = @"<bucketname>";
            compMultipartRequest.key = @"<objectname>";
            compMultipartRequest.uploadId = uploadID;
            compMultipartRequest.parts = parts;
            
            __block BOSCompleteMultipartUploadResponse* complResponse = nil;
            task = [client completeMultipartUpload:compMultipartRequest];
            task.then(^(BCEOutput* output) {
              if (output.response) {
                  complResponse = (BOSCompleteMultipartUploadResponse*)output.response;
                  NSLog(@"complte multiparts success!");
              }
            
              if (output.error) {
                  NSLog(@"complte multiparts failure %@", output.error);
              }
            });
            [task waitUtilFinished];

            说明:上面代码中的 parts 是第二步中保存的parts的列表,BOS收到用户提交的Part列表后,会逐一验证每个数据Part的有效性。当所有的数据Part验证通过后,BOS将把这些数据part组合成一个完整的Object。

          • 完整示例

            #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];
            
            // 初始化分块上传
            BOSInitiateMultipartUploadRequest* initMPRequest = [[BOSInitiateMultipartUploadRequest alloc] init];
            initMPRequest.bucket = @"<bucketname>";
            initMPRequest.key = @"<objectname>";
            initMPRequest.contentType = @"<content type>";
            
             __block BOSInitiateMultipartUploadResponse* initMPResponse = nil;
             BCETask* task = [client initiateMultipartUpload:initMPRequest];
             task.then(^(BCEOutput* output) {
                 if (output.response) {
                     initMPResponse = (BOSInitiateMultipartUploadResponse*)output.response;
                     NSLog(@"initiate multipart upload success!");
                 }
            
                 if (output.error) {
                     NSLog(@"initiate multipart upload failure");
                 }
             });
             [task waitUtilFinished];
            
             NSString* uploadID = initMPResponse.uploadId;
            
             // 计算分块个数
             NSString* file = @"/path/to/file.zip";
             NSDictionary<NSString*, id>* attr = [[NSFileManager defaultManager] attributesOfItemAtPath:file error:nil];
             uint64_t fileSize = attr.fileSize;
             uint64_t partSize = 1024 * 1024 * 5L;
             uint64_t partCount = fileSize / partSize;
             if (fileSize % partSize != 0) {
                 ++partCount;
             }
            
             NSMutableArray<BOSPart*>* parts = [NSMutableArray array];
            
             NSFileHandle* handle = [NSFileHandle fileHandleForReadingAtPath:@"/path/to/file.zip"];
             for (uint64_t i = 0; i < partCount; ++i) {
                 // seek
                 uint64_t skip = partSize * i;
                 [handle seekToFileOffset:skip];
                 uint64_t size = (partSize < fileSize - skip) ? partSize : fileSize - skip;
            
                 // data
                 NSData* data = [handle readDataOfLength:size];
            
                 // request
                 BOSUploadPartRequest* uploadPartRequest = [[BOSUploadPartRequest alloc] init];
                 uploadPartRequest.bucket = @"<bucketname>";
                 uploadPartRequest.key = @"<objectname>";
                 uploadPartRequest.objectData.data = data;
                 uploadPartRequest.partNumber = i + 1;
                 uploadPartRequest.uploadId = uploadID;
            
                 __block BOSUploadPartResponse* uploadPartResponse = nil;
                 task = [client uploadPart:uploadPartRequest];
                 task.then(^(BCEOutput* output) {
                     if (output.response) {
                         uploadPartResponse = (BOSUploadPartResponse*)output.response;
                         BOSPart* part = [[BOSPart alloc] init];
                         part.partNumber = i + 1;
                         part.eTag = uploadPartResponse.eTag;
                                 [parts addObject:part];
                     }
                 });
                 [task waitUtilFinished];
             }
            
             BOSCompleteMultipartUploadRequest* compMultipartRequest = [[BOSCompleteMultipartUploadRequest alloc] init];
             compMultipartRequest.bucket = @"<bucketname>";
             compMultipartRequest.key = @"<objectname>";
             compMultipartRequest.uploadId = uploadID;
             compMultipartRequest.parts = parts;
            
             __block BOSCompleteMultipartUploadResponse* complResponse = nil;
             task = [client completeMultipartUpload:compMultipartRequest];
             task.then(^(BCEOutput* output) {
                 if (output.response) {
                     complResponse = (BOSCompleteMultipartUploadResponse*)output.response;
                     NSLog(@"complte multiparts success!");
                 }
            
                 if (output.error) {
                     NSLog(@"complte multiparts failure %@", output.error);
                 }
             });
             [task waitUtilFinished];
            }

          取消分块上传

          用户可以使用abortMultipartUpload方法取消分块上传。

          • 示例代码

            BOSAbortMultipartUploadRequest* abortRequest = [[BOSAbortMultipartUploadRequest alloc] init];
            abortRequest.bucket = @"bucket";
            abortRequest.key = @"<objectname>";
            abortRequest.uploadId = uploadID;
            
            __block BOSAbortMultipartUploadResponse* abortResponse = nil;
            task = [client abortMultipartUpload:abortRequest];
            task.then(^(BCEOutput* output) {
              if (output.response) {
                  abortResponse = (BOSAbortMultipartUploadResponse*)output.response;
                  NSLog(@"abort multiparts success!");
              }
            
              if (output.error) {
                  NSLog(@"abort multiparts failure %@", output.error);
              }
            });
            [task waitUtilFinished];

          获取未完成的分块上传

          用户可以使用listMultipartUploads方法获取Bucket内未完成的分块上传事件。

          • 基本流程

            1. 创建BOSListMultipartUploadsRequest类的实例,传入<BucketName>参数。
            2. 创建BOSClient类的实例,执行BOSClient listMultipartUploads方法。
            3. listMultipartUploads返回所有未完成的分块上传信息。
          • 示例代码

            BOSListMultipartUploadsRequest* listMultipartRequest = [[BOSListMultipartUploadsRequest alloc] init];
            listMultipartRequest.bucket = @"<bucketname>";
            
            __block BOSListMultipartUploadsResponse* listMultipartResponse = nil;
            task = [client listMultipartUploads:listMultipartRequest];
            task.then(^(BCEOutput* output) {
              if (output.response) {
                  listMultipartResponse = (BOSListMultipartUploadsResponse*)output.response;
                  NSLog(@"list multipart success");
              }
            
              if (output.error) {
                  NSLog(@"list multipart failure %@", output.error);
              }
            });
            [task waitUtilFinished];

            注意:

            • 默认情况下,如果Bucket中的分块上传事件的数目大于1000,则只会返回1000个Object,并且返回结果中IsTruncated的值为True,同时返回nextKeyMarker作为下次读取的起点。
            • 若想获取更多分块上传事件,可以使用keyMarker参数分次读取。
          • 完整示例

            #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];
            
                BOSListMultipartUploadsRequest* listMultipartRequest = [[BOSListMultipartUploadsRequest alloc] init];
                listMultipartRequest.bucket = @"<bucketname>";
            
                __block BOSListMultipartUploadsResponse* listMultipartResponse = nil;
                BCETask* task = [client listMultipartUploads:listMultipartRequest];
                task.then(^(BCEOutput* output) {
                  if (output.response) {
                      listMultipartResponse = (BOSListMultipartUploadsResponse*)output.response;
                      NSLog(@"list multipart success");
                  }
            
                  if (output.error) {
                      NSLog(@"list multipart failure %@", output.error);
                  }
                });
                [task waitUtilFinished];
            
                for (BOSMultipartUpload* upload in listMultipartResponse.uploads) {
                    NSLog(@"upload id : %@", upload.uploadId);
                }
            }

          获取所有已上传的分块信息

          用户可以使用listParts方法获取某个上传事件中所有已上传的块。

          • 基本流程

            1. 创建BOSListPartsRequest类的实例,传入<BucketName>,<ObjectKey>, <UploadId>参数。
            2. 创建BOSClient类的实例,执行BOSClient listParts方法。
            3. listParts返回所有已上传part的信息。
          • 示例代码

            BOSListPartsRequest* listPartsRequest = [[BOSListPartsRequest alloc] init];
            listPartsRequest.bucket = @"<bucketname>";
            listPartsRequest.key = @"<objectname>";
            listPartsRequest.uploadId = @"<upload id>";;
            
            __block BOSListPartsResponse* listPartsResponse = nil;
            BCETask* task = [client listParts:listPartsRequest];
            task.then(^(BCEOutput* output) {
              if (output.response) {
                  listPartsResponse = (BOSListPartsResponse*)output.response;
                  NSLog(@"list parts success!");
              }
            
              if (output.error) {
                  NSLog(@"list part failure %@", output.error);
              }
            });
            [task waitUtilFinished];
            
            for (BOSPart* part in listPartsResponse.parts) {
                NSLog(@"part etag %@", part.eTag);
            }

            注意:

            • 默认情况下,如果Bucket中的分块上传事件的数目大于1000,则只会返回1000个Object,并且返回结果中IsTruncated的值为True,同时返回NextPartNumberMarker作为下次读取的起点。
            • 若想获取更多已上传的分块信息,可以使用PartNumberMarker参数分次读取。
          • 完整示例

            #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];
            
                BOSListPartsRequest* listPartsRequest = [[BOSListPartsRequest alloc] init];
                listPartsRequest.bucket = @"<bucketname>";
                listPartsRequest.key = @"<objectname>";
                listPartsRequest.uploadId = @"<upload id>";;
            
                __block BOSListPartsResponse* listPartsResponse = nil;
                BCETask* task = [client listParts:listPartsRequest];
                task.then(^(BCEOutput* output) {
                if (output.response) {
                    listPartsResponse = (BOSListPartsResponse*)output.response;
                    NSLog(@"list parts success!");
                }
            
                if (output.error) {
                    NSLog(@"list part failure %@", output.error);
                }
                });
                [task waitUtilFinished];
            
                for (BOSPart* part in listPartsResponse.parts) {
                    NSLog(@"part etag %@", part.eTag);
                }
            }
          上一篇
          Bucket管理
          下一篇
          日志