Object Management
Object Uploading
The Simplest Uploading
-
Basic procedure
1.Create an instance of the BOSClient class. 2.Call BOSClient putObject method, and upload object in the following 2 ways: Form of file and binary system 3.For the returned BOSPutObjectResponse type instance, execute the obtaining of eTag operation.
-
Sample Code
BOSObjectContent* content = [[BOSObjectContent alloc] init]; // In file form content.objectData.file = @"<file path>"; // Or in binary data form 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];
Note: Upload object to BOS in the file form. objects no more than 5 GB can be uploaded through putObject. After the putObject request is successfully processed, BOS will return the ETag of object as a file identifier in the Header.
-
Complete example
#import <BaiduBCEBasic/BaiduBCEBasic.h> #import <BaiduBCEBOS/BaiduBCEBOS.h> void example(void) { // Initialization 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]; // In file form content.objectData.file = @"<file path>"; // Or in binary data form 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]; }
Set the Http Header of Object
Under BOS, Http Header setting is available during object uploading.
-
Basic procedure
1.Create instance of BOSObjectMetadata class 2.Set contentEncoding/contentType/contentDisposition and other fields of BOSObjectMetadata 3.Set BOSObjectMetadata instance to ObjectContent.metadata field of BOSPutObjectRequest.
-
Sample Code
BOSObjectMetadata* metadata = [[BOSObjectMetadata alloc] init]; metadata.contentEncoding = @"<encoding>"; metadata.contentDisposition = @"<content disposition>"; content.metadata = metadata;
-
Complete example
#import<BaiduBCEBasic/BaiduBCEBasic.h> #import<BaiduBCEBOS/BaiduBCEBOS.h> void example(void) { // Initialization 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]; // In file form content.objectData.file = @"<file path>"; // Or in binary data form 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]; }
Custom Metadata
Custom metadata is available under BOS for object description.
-
Basic procedure
1.Create instance of BOSObjectMetadata class 2.Set custom metadata dictionary to userMetadata field of BOSObjectMetadata.
-
Sample Code
BOSObjectMetadata* metadata = [[BOSObjectMetadata alloc] init]; metadata.contentEncoding = @"<encoding>"; metadata.contentDisposition = @"<content disposition>"; content.metadata = metadata; NSDictionary* customMetadata = @{ @"name" : @"my-data" }; content.metadata.userMetadata = customMetadata;
Note: As for the above code, users have customized a metadata of which the name is "name" and the value is "my-data". When users download this object, they can get metadata together. One object possesses similar parameters, but the total size of User Meta bellows 2KB.
-
Complete example
#import<BaiduBCEBasic/BaiduBCEBasic.h> #import<BaiduBCEBOS/BaiduBCEBOS.h> void example(void) { // Initialization 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]; // In file form content.objectData.file = @"<file path>"; // Or in binary data form 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]; }
View the Object in Bucket
Simple Search
View the object list in bucket.
-
Basic procedure
1.Create an instance of the BOSClient class. 2.Execute BOSClient listobjects method to return instance of BOSListobjectsResponse class 3.Contents field of BOSListobjectsResponse can be enumerated to obtain key/lastModified/eTag/size/owner.
-
Sample Code
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];
Note: Listobjects method returns BOSListobjectsResponse object which contains the return result of the current listobject request. Users can obtain descriptive information of all objects via contents attribute in BOSListobjectsResponse.
- By default, if the number of object in bucket is more than 1,000, only 1,000 objects are returned, and the value of isTruncated in returned result is YES, and nextMarker is returned as the starting point of the next reading.
- Use the Marker parameter to access more objects in batches. Refer to [query expansion](#query expansion).
-
Complete example
#import <BaiduBCEBasic/BaiduBCEBasic.h> #import <BaiduBCEBOS/BaiduBCEBOS.h> void example(void) { // Initialization 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]; }
Query Expansion
You can set more extension inquiry operations by setting BOSListobjectsResquest parameters. Available extension parameters of BOSListobjectsResquest are as follows:
Parameter name | Description | Default value |
---|---|---|
maxKeys | Set the maximum number of objects returned this time as 1000. | 1000 |
prefix | Sets the prefix of ObjectKey, which covers and starts with the value of Prefix. Used in [Inquire Simulated Folder](#Inquire Simulated Folder) in cooperation with delimiter generally | - |
delimiter | A delimiter, used to make ObjectKey hierarchies. Used in [Inquire Simulated Folder](#Inquire Simulated Folder) in cooperation with prefix generally The ObjectKey from prefix to first appearing of delimiter character is referred to as: commonPrefixes | - |
marker | A character string, used to set the starting position of the returned result. After setting marker value, the object returned is returned in alphabetical order after marker value. | - |
-
Basic procedure
1.Create instance of BOSListobjectsResquest type 2.Set delimiter/marker/prefix/maxKeys and other fields of BOSListobjectsResquest for more extension inquiry operations. 3.Create the instance of BOSClient class, and execute listobjects.
-
Sample Code
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];
-
Complete example
Example I:
#import <BaiduBCEBasic/BaiduBCEBasic.h> #import <BaiduBCEBOS/BaiduBCEBOS.h> void example(void) { // Initialization 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]; }
Example II: Use the complete example of nextMarker.
#import <BaiduBCEBasic/BaiduBCEBasic.h>
#import <BaiduBCEBOS/BaiduBCEBOS.h>
void example(void) {
// Initialization
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);
}
}
});
}
}
Search for Simulation Folders
BOS itself is a storage system of (<Key>,<Value>
), so there is no concept of folder in principle, but you can simulate folder function through the cooperation of delimiter
and prefix
parameters.
Suppose bucket have 5 files: bos.jpg, fun/, fun/test.jpg, fun/movie/001.avi, fun/movie/007.avi ("/" can be used as a delimiter to simulate folders.)
Lists All Files in Simulation Folders Recursively
All folders under a simulated folder can be obtained by setting prefix
parameter:
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];
Output:
Objects:
fun/
fun/movie/001.avi
fun/movie/007.avi
fun/test.jpg
Check the Files and Subfolders in Simulation Folders
When prefix
is combined with delimiter
, the files and subdirectories under simulated folder can be listed:
BOSListObjectsRequest* listObjRequest = [[BOSListObjectsRequest alloc] init];
listObjRequest.bucket = @"<bucketname>";
// Designate "/" as the delimiter for of simulation folders
listObjRequest.delimiter = @"/";
// List all files and subfolders in fun folders
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];
// Traverse all objects
NSLog(@"Objects:");
for (BOSObjectInfo* object in listObjResponse.contents) {
NSLog(@"%@", object.key);
}
// Traverse all CommonPrefix
NSLog(@"CommonPrefixs:");
for (NSString* commonPrefix in listObjResponse.commonPrefixes) {
NSLog(@"%@", commonPrefix);
}
Output:
Objects:
fun/
fun/test.jpg
CommonPrefixs:
fun/movie/
Note: In the result returned, the list of
contents
gives files under fun folder. The list ofcommonPrefixs
gives all sub-folders under fun folder. It is clear that thefun/movie/001.avi
file andfun/movie/007.avi
file are not listed because they are the files in themovie
subfolder under thefun
folder.
Access Object
Access Object Easily
Users can read object to memory via the following codes.
-
Basic procedure
1.Create an instance of the BOSClient class. 2.Execute BOSClient getobject method to return BOSGetObjectResponse instance. 3.Access ObjectContent.objectData.data attribute of BOSGetObjectResponse example to obtain data.
-
Sample Code
__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]; // Obtain data in memory NSData* data = getObjResponse.objectContent.objectData.data;
Note:
- BOSObjectContent contains various information of object, including bucket of object, object name, MetaData and data storage.
- BOSObjectMetadata contains the ETag defined when the object is uploaded, the Http Header, and the custom metadata.
- object data are obtained via objectData attribute of BOSObjectContent
-
Complete example
#import <BaiduBCEBasic/BaiduBCEBasic.h> #import <BaiduBCEBOS/BaiduBCEBOS.h> void example(void) { // Initialization 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; }
Download a Part of Contents of Object
-
Basic procedure
1.Create instance of BOSGetObjectRequest class 2.rangeStart and/or rangeEnd fields of BOSGetObjectRequestt instance 3.Execute client getobject operation.
-
Sample Code
__block BOSGetObjectResponse* getObjResponse = nil; BOSGetObjectRequest* getObjRequest = [[BOSGetObjectRequest alloc] init]; getObjRequest.bucket = @"<bucketname>"; getObjRequest.key = @"<objectname>"; // Obtain the first 100 bytes 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;
Note: You can use this function for segmented download of file and breakpoint continued upload.
Download Object to the Specified Path
You can download object directly to the specified path through the following code.
-
Basic procedure
1.Create instance of BOSGetObjectRequest class 2.Set the file name to be saved to file field of BOSGetObjectRequest instance. 3.Execute client getobject operation. 4.object can be downloaded to the specified path.
-
Sample Code
__block BOSGetObjectResponse* getObjResponse = nil; BOSGetObjectRequest* getObjRequest = [[BOSGetObjectRequest alloc] init]; getObjRequest.bucket = @"<bucketname>"; getObjRequest.key = @"<objectname>"; // Save file path to which the file is saved 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];
Get the StorageClass of the Object
The storage class attribute of object is classified into STANDARD (standard storage), STANDARD_IA (infrequency storage) and COLD (cold storage)
Sample Code
__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];
Get only ObjectMetadata
Through the getObjectMetadata method, you can only get the object metadata without getting the object entity.
- Sample Code
__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];
Get the URL of Object
You can get the URL of the specified object through the following code. This feature is typically used for scenarios where you temporarily share the URL of an object with other users.
-
Basic procedure
1.Create an instance of the BOSClient class. 2.Execute BOSClient generatePresignedUrl method 3.Return an object URL.
-
Sample Code
__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); }
Note: ExpirationInSeconds is the effective time length of specified URL, calculated from the current time, and it is an optional parameter; when not configured, the system default value is 1,800sec. To set a time not invalid permanently, ExpirationInSeconds parameter can be set as -1, and it cannot be set as other negative numbers.
-
Complete example
#import <BaiduBCEBasic/BaiduBCEBasic.h> #import <BaiduBCEBOS/BaiduBCEBOS.h> void example(void) { // Initialization 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); } }
Delete Object
-
Basic procedure
1.Create an instance of the BOSClient class. 2.Execute BOSClient deleteobject method 3.If an error is generated after operation fails.
- Sample Code
__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];
- Complete example
#import <BaiduBCEBasic/BaiduBCEBasic.h>
#import <BaiduBCEBOS/BaiduBCEBOS.h>
void example(void) {
// initialization
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];
}
Copy Object
Simply copy object
-
Basic procedure
1.Create an instance of the BOSClient class. 2.Execute BOSClient copyobject method. 3.Return BOSCopyObjectResponse instance to obtain eTag and last modification time via eTag/lastModified and other attributes.
-
Sample Code
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];
-
Complete example
#import <BaiduBCEBasic/BaiduBCEBasic.h> #import <BaiduBCEBOS/BaiduBCEBOS.h> void example(void) { // Initialization 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]; }
Note: Copyobject method returns a
BOSCopyObjectResponse
object which contains the ETag and modification time of a new object.
Copy Object of Specified Condition
You can also copy object via a specified condition This feature is typically used in the following scenarios:
- Copy an object but reset the meta.
- Set the meta of an existing object (set the source and target as the same object)
- Copy when the eTag of source object is the same with the specified eTag
- Copy when the eTag of source object is different from the specified eTag
- Copy when the eTag of source object is not modified after the specified time;
- Copy when the eTag of source object is modified after the specified time;
The specific contents are as follows:
-
Basic procedure
1.Create instance of BOSCopyObjectRequest class, transmit
<source>
,<ifMatchEtag>
,<ifNotMatchEtag>
,<ifModifiedSince>
,<ifUnmodifiedSince>
,<metadataDirective>
parameters. 2.Return instance of BOSCopyObjectResponse class, and eTag and last modification time can be obtained via eTag/lastModified attribute. -
Sample Code
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];
Note:
BOSCopyObjectRequest
allows users to modify objectMeta of destination object, whole providing setting ofMatchingETagConstraints
parameter.
Multipart Upload of Object
In addition to uploading files to BOS through putObject () method, BOS also provides another upload mode: Multipart Upload. You can use the Multipart Upload mode in the following application scenarios (but not limited to this), such as:
- Breakpoint upload support is required.
- The file to upload is larger than 5 GB.
- The network conditions are poor, and the connection with BOS servers is often disconnected.
- The file needs to be uploaded streaming.
- The size of the uploaded file cannot be determined before uploading it.
Complete Multipart Upload
Suppose you have a file with the local path of /path/to/file.zip
, upload it through Multipart Upload to BOS for its large size.
-
Basic procedure
1.Initialize Multipart Upload. 2.Upload in parts. 3.Complete Multipart Upload.
Initialize Multipart Upload
Use the initiateMultipartUpload
method to initialize a Multipart Upload event:
-
Sample Code
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;
Note: The returned result of
initiateMultipartUpload
containsuploadId
, which is the unique identification to distinguish upload by event part, and we will use it in the subsequent operation.
Upload in Parts
Upload files in parts.
-
Sample Code
// Calculate number of parts 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]; }
Note: The core of the code above is to call
uploadPart
method to upload each part, but the following need to be noted:- The UploadPart method requires that all but the last Part be larger than or equal to 5 MB. However, the Upload Part interface does not immediately verify the size of the Upload Part. It verifies only in case of Complete Multipart Upload.
- To ensure no error occurs to data in the network transmission process, it is recommended that you use the Content-MD5 value returned by each part BOS to verify the correctness of the uploaded part data respectively after
UploadPart
. When all part data is combined into one object, it no longer contains the MD5 value. - Part numbers range from 1 to 10,000. If this range is exceeded, BOS will return the error code of InvalidArgument.
- Every time you upload a Part, locate the stream to the location corresponding to the beginning of the uploaded part.
- After uploading Part each time, the returned result of BOS contains a
BOSPart
object, which is the combination of ETag of uploaded part and PartNumber, and will be used in the subsequent multipart upload, so it needs to be saved. Generally, theseBOSPart
objects are saved in List.
Complete Multipart Upload
-
Sample Code
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];
Note: The
parts
in the code above are the list of parts saved in Step 2 and BOS checks the validity of each data Part after receiving the Part list submitted by users. When all data Parts are verified, BOS will combine these data parts into a complete object. -
Complete example
#import <BaiduBCEBasic/BaiduBCEBasic.h> #import <BaiduBCEBOS/BaiduBCEBOS.h> void example(void) { // Initialization 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]; // Initialize multipart upload 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; // Calculate number of parts 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]; }
Cancel Multipart Upload
You can use the abortMultipartUpload method to cancel Multipart Upload.
-
Sample Code
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];
Get Unfinished Multipart Upload
You can use the listMultipartUploads
method to get unfinished Multipart Upload events in the bucket.
-
Basic procedure
1.Create the instance of BOSListMultipartUploadsRequest class, and introduce
<BucketName>
parameter. 2.Create instance of BOSClient, and execute BOSClient listMultipartUploads method. 3.ListMultipartUploads returns all uncompleted multipart upload information. -
Sample Code
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];
Note:
- By default, only 1,000 objects are returned and the IsTruncated value is True if the number of Multipart Upload events in bucket is over 1,000. Besides, NextKeyMarker is returned as the starting point for the next reading.
- For more Multipart Upload events, you can use the KeyMarker parameter to read them by several times.
-
Complete example
#import <BaiduBCEBasic/BaiduBCEBasic.h> #import <BaiduBCEBOS/BaiduBCEBOS.h> void example(void) { // Initialization 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); } }
Get All Uploaded Part Information
You can use the listParts
method to get all uploaded parts in an uploaded event.
-
Basic procedure
1.Create instance of BOSListPartsRequest class, and introduce
<BucketName>
,<ObjectKey>
,<UploadId>
parameters. 2.Create the instance of BOSClient class, and execute BOSClient listParts method. 3.listParts returns information about all uploaded parts. -
Sample Code
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); }
Note:
- By default, only 1,000 objects are returned and the IsTruncated value is True if the number of Multipart Upload events in bucket is over 1,000. Besides, NextPartNumberMarker is returned as the starting point for the next reading.
- For more uploaded part information, you can use the PartNumberMarker parameter to read it by several times.
-
Complete example
#import <BaiduBCEBasic/BaiduBCEBasic.h> #import <BaiduBCEBOS/BaiduBCEBOS.h> void example(void) { // Initialization 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); } }