
# 列举多版本对象
您可以通过OBSListObjectsVersionsRequest列举多版本对象。
该接口可设置的参数如下：
| **参数**          | **作用**                                                                                                                     |
|:---|:---|
| bucketName      | 桶名。                                                                                                                        |
| prefix          | 限定返回的对象名必须带有prefix前缀。                                                                                                      |
| keyMarker       | 列举多版本对象的起始位置，返回的对象列表将是对象名按照字典序排序后该参数以后的所有对象。                                                                               |
| maxKeys         | 列举多版本对象的最大数目，取值范围为1\~1000，当超出范围时，按照默认的1000进行处理。                                                                            |
| delimiter       | 用于对对象名进行分组的字符。对于对象名中包含delimiter的对象，其对象名（如果请求中指定了prefix，则此处的对象名需要去掉prefix）中从首字符至第一个delimiter之间的字符串将作为一个分组并作为commonPrefix返回。 |
| versionIDMarker | 与keyMarker配合使用，返回的对象列表将是对象名和版本号按照字典序排序后该参数以后的所有对象。                                                                         |
   
![](https://support.huaweicloud.com/sdk-ios-devg-obs/public_sys-resources/note_3.0-zh-cn.png)
- 如果versionIDMarker不是keyMarker的一个版本号，则该参数无效。
- OBSListObjectsVersionsRequest返回结果包含多版本对象和对象删除标记。
 
#### 简单列举
以下代码展示如何简单列举多版本对象，最多返回1000个对象：
```
static OBSClient *client;
NSString *endPoint = @"https://your-endpoint";
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量AccessKeyID和SecretAccessKey。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
char* ak_env = getenv("AccessKeyID");
char* sk_env = getenv("SecretAccessKey");
if (ak_env == NULL || sk_env == NULL) {
    NSLog(@"Error: AccessKeyID or SecretAccessKey environment variable not set");
    return;
}
NSString *AK = [NSString stringWithUTF8String:ak_env];
NSString *SK = [NSString stringWithUTF8String:sk_env];
    
// 初始化身份验证
 OBSStaticCredentialProvider *credentialProvider = [[OBSStaticCredentialProvider alloc] initWithAccessKey:AK secretKey:SK];
   
//初始化服务配置
OBSServiceConfiguration *conf = [[OBSServiceConfiguration alloc] initWithURLString:endPoint credentialProvider:credentialProvider];
    
// 初始化client
client = [[OBSClient alloc] initWithConfiguration:conf];
    
// 列举多版本对象
OBSListObjectsVersionsRequest *request = [[OBSListObjectsVersionsRequest alloc] initWithBucketName:@"bucketname"];
    
[client listObjectsVersions:request completionHandler:^(OBSListObjectsVersionsResponse *response, NSError *error) {
     for (int i =0; i<response.versionList.count; i++) {
        NSLog(@"%@ \n",response.versionList[i].key);
    }
 }];
```
![](https://support.huaweicloud.com/sdk-ios-devg-obs/public_sys-resources/note_3.0-zh-cn.png)
- 每次至多返回1000个多版本对象，如果指定桶包含的对象数量大于1000，则返回结果中response.isTruncated为YES表明本次没有返回全部对象，并可通过response.nextKeyMarker和response.versionIdMarker获取下次列举的起始位置。
- 如果想获取指定桶包含的所有多版本对象，可以采用分页列举的方式。
 
#### 指定数目列举
以下代码展示如何指定数目列举多版本对象：
```
static OBSClient *client;
NSString *endPoint = @"https://your-endpoint";
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量AccessKeyID和SecretAccessKey。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
char* ak_env = getenv("AccessKeyID");
char* sk_env = getenv("SecretAccessKey");
if (ak_env == NULL || sk_env == NULL) {
    NSLog(@"Error: AccessKeyID or SecretAccessKey environment variable not set");
    return;
}
NSString *AK = [NSString stringWithUTF8String:ak_env];
NSString *SK = [NSString stringWithUTF8String:sk_env];
    
// 初始化身份验证
OBSStaticCredentialProvider *credentialProvider = [[OBSStaticCredentialProvider alloc] initWithAccessKey:AK secretKey:SK];
    
//初始化服务配置
OBSServiceConfiguration *conf = [[OBSServiceConfiguration alloc] initWithURLString:endPoint credentialProvider:credentialProvider];
    
// 初始化client
client = [[OBSClient alloc] initWithConfiguration:conf];
    
// 列举多版本对象
OBSListObjectsVersionsRequest *request = [[OBSListObjectsVersionsRequest alloc] initWithBucketName:@"bucketname"];
    
// 最大列举100条
request.maxKeys = [NSNumber numberWithInt:100];
    
    
[client listObjectsVersions:request completionHandler:^(OBSListObjectsVersionsResponse *response, NSError *error) {
     for (int i =0; i<response.versionList.count; i++) {
        NSLog(@"%@ \n",response.versionList[i].key);
   }
}];
```
#### 指定前缀列举
以下代码展示如何指定前缀列举多版本对象：
```
static OBSClient *client;
NSString *endPoint = @"https://your-endpoint";
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量AccessKeyID和SecretAccessKey。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
char* ak_env = getenv("AccessKeyID");
char* sk_env = getenv("SecretAccessKey");
if (ak_env == NULL || sk_env == NULL) {
    NSLog(@"Error: AccessKeyID or SecretAccessKey environment variable not set");
    return;
}
NSString *AK = [NSString stringWithUTF8String:ak_env];
NSString *SK = [NSString stringWithUTF8String:sk_env];
    
// 初始化身份验证
OBSStaticCredentialProvider *credentialProvider = [[OBSStaticCredentialProvider alloc] initWithAccessKey:AK secretKey:SK];
    
//初始化服务配置
OBSServiceConfiguration *conf = [[OBSServiceConfiguration alloc] initWithURLString:endPoint credentialProvider:credentialProvider];
    
// 初始化client
client = [[OBSClient alloc] initWithConfiguration:conf];
    
// 列举多版本对象
OBSListObjectsVersionsRequest *request = [[OBSListObjectsVersionsRequest alloc] initWithBucketName:@"bucketname"];
    
// 指定前缀列举
request.prefix = @"/";
    
[client listObjectsVersions:request completionHandler:^(OBSListObjectsVersionsResponse *response, NSError *error) {
     for (int i =0; i<response.versionList.count; i++) {
        NSLog(@"%@ \n",response.versionList[i].key);
    }
        
}];
```
#### 指定起始位置列举
以下代码展示如何指定起始位置列举多版本对象：
```
static OBSClient *client;
NSString *endPoint = @"https://your-endpoint";
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量AccessKeyID和SecretAccessKey。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
char* ak_env = getenv("AccessKeyID");
char* sk_env = getenv("SecretAccessKey");
if (ak_env == NULL || sk_env == NULL) {
    NSLog(@"Error: AccessKeyID or SecretAccessKey environment variable not set");
    return;
}
NSString *AK = [NSString stringWithUTF8String:ak_env];
NSString *SK = [NSString stringWithUTF8String:sk_env];
    
// 初始化身份验证
OBSStaticCredentialProvider *credentialProvider = [[OBSStaticCredentialProvider alloc] initWithAccessKey:AK secretKey:SK];
    
//初始化服务配置
OBSServiceConfiguration *conf = [[OBSServiceConfiguration alloc] initWithURLString:endPoint credentialProvider:credentialProvider];
    
// 初始化client
client = [[OBSClient alloc] initWithConfiguration:conf];
    
// 列举多版本对象
OBSListObjectsVersionsRequest *request = [[OBSListObjectsVersionsRequest alloc] initWithBucketName:@"bucketname"];
    
// 指定位置列举
request.keyMarker = @"/";
    
[client listObjectsVersions:request completionHandler:^(OBSListObjectsVersionsResponse *response, NSError *error) {
     for (int i =0; i<response.versionList.count; i++) {
        NSLog(@"%@ \n",response.versionList[i].key);
    }
}];
```
#### 分页列举全部多版本对象
以下代码展示分页列举全部多版本对象：
```
static OBSClient *client;
NSString *endPoint = @"https://your-endpoint";
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量AccessKeyID和SecretAccessKey。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
char* ak_env = getenv("AccessKeyID");
char* sk_env = getenv("SecretAccessKey");
if (ak_env == NULL || sk_env == NULL) {
    NSLog(@"Error: AccessKeyID or SecretAccessKey environment variable not set");
    return;
}
NSString *AK = [NSString stringWithUTF8String:ak_env];
NSString *SK = [NSString stringWithUTF8String:sk_env];
    
// 初始化身份验证
OBSStaticCredentialProvider *credentialProvider = [[OBSStaticCredentialProvider alloc] initWithAccessKey:AK secretKey:SK];
    
//初始化服务配置
OBSServiceConfiguration *conf = [[OBSServiceConfiguration alloc] initWithURLString:endPoint credentialProvider:credentialProvider];
    
// 初始化client
client = [[OBSClient alloc] initWithConfiguration:conf];
    
// 列举多版本对象
    
__block OBSListObjectsVersionsResponse *result;
    
    // 列举对象
OBSListObjectsVersionsRequest *request = [[OBSListObjectsVersionsRequest alloc] initWithBucketName:@"bucketname"];
    
request.maxKeys = [NSNumber numberWithInt:1];
// 列举全部对象
do {
    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    [client listObjectsVersions:request completionHandler:^(OBSListObjectsVersionsResponse *response, NSError *error) {
        result = response;
     for (int i =0; i<response.versionList.count; i++) {
        NSLog(@"%@ \n",response.versionList[i].key);
    }
        request.keyMarker = result.nextKeyMarker;
        dispatch_semaphore_signal(sema);
   }];
   dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 300 * NSEC_PER_SEC));
} while (result.isTruncated);
```
#### 列举文件夹中的所有多版本对象
OBS本身是没有文件夹的概念的，桶中存储的元素只有对象。文件夹对象实际上是一个大小为0且对象名以"/"结尾的对象，将这个文件夹对象名作为前缀，即可模拟列举文件夹中对象的功能。以下代码展示如何列举文件夹中的多版本对象：
```
static OBSClient *client;
NSString *endPoint = @"https://your-endpoint";
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量AccessKeyID和SecretAccessKey。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
char* ak_env = getenv("AccessKeyID");
char* sk_env = getenv("SecretAccessKey");
if (ak_env == NULL || sk_env == NULL) {
    NSLog(@"Error: AccessKeyID or SecretAccessKey environment variable not set");
    return;
}
NSString *AK = [NSString stringWithUTF8String:ak_env];
NSString *SK = [NSString stringWithUTF8String:sk_env];
    
// 初始化身份验证
OBSStaticCredentialProvider *credentialProvider = [[OBSStaticCredentialProvider alloc] initWithAccessKey:AK secretKey:SK];
    
//初始化服务配置
OBSServiceConfiguration *conf = [[OBSServiceConfiguration alloc] initWithURLString:endPoint credentialProvider:credentialProvider];
    
// 初始化client
client = [[OBSClient alloc] initWithConfiguration:conf];
    
// 列举多版本对象
// 列举对象
OBSListObjectsVersionsRequest *request = [[OBSListObjectsVersionsRequest alloc] initWithBucketName:@"bucketname"];
    
request.delimiter = @"/";
// 根目录中的对象
[client listObjectsVersions:request completionHandler:^(OBSListObjectsVersionsResponse *response, NSError *error) {
        
    for (int i =0; i<response.versionList.count; i++) {
        NSLog(@"%@ \n",response.versionList[i].key);
    }
    [self listVersionObjectsByPrefix:client request:request result:response];
}];
```
listVersionObjectsByPrefix函数：
```
-(void) listVersionObjectsByPrefix:(OBSClient*) client request:(OBSListObjectsVersionsRequest *) request result:            (OBSListObjectsVersionsResponse*) result{
    
    for (NSString * prefix in result.commonPrefixesList){
        NSLog(@"文件夹[%@]中的对象:",prefix);
        request.prefix = prefix;
        [client listObjectsVersions:request completionHandler:^(OBSListObjectsVersionsResponse *response, NSError *error) {
            for (int i =0; i<response.versionList.count; i++) {
                NSLog(@"%@ \n",response.versionList[i].key);
            }
            [self listVersionObjectsByPrefix:client request:request result:response];
        }];
    }
    
}
```
![](https://support.huaweicloud.com/sdk-ios-devg-obs/public_sys-resources/note_3.0-zh-cn.png)
- 以上代码示例没有考虑文件夹中多版本对象数超过1000个的情况。
- 由于是需要列举出文件夹中的对象和子文件夹，且文件夹对象总是以"/"结尾，因此delimiter总是为"/"。
- 每次递归的返回结果中ListVersionsResult.getVersions包含的是文件夹中的多版本对象；ListVersionsResult.getCommonPrefixes包含的是文件夹的子文件夹。
 
