
# 列举对象
![](https://support.huaweicloud.com/sdk-android-devg-obs/public_sys-resources/notice_3.0-zh-cn.png)
开发过程中，您有任何问题可以在github上[提交issue](https://github.com/huaweicloud/huaweicloud-sdk-java-obs/issues)，或者在[华为云对象存储服务论坛](https://bbs.huaweicloud.com/forum/forum-620-1.html)中发帖求助。[接口参考文档](https://obssdk.obs.cn-north-1.myhuaweicloud.com/apidoc/cn/android/index.html)详细介绍了每个接口的参数和使用方法。
您可以通过ObsClient.listObjects列举出桶里的对象。
该接口可设置的参数如下：
| **参数**     | **作用**                                                                                                                                                                                                                                                                      | **OBS Android SDK对应方法**          |
|:---|:---|:---|
| bucketName | 桶名。                                                                                                                                                                                                                                                                         | ListObjectsRequest.setBucketName |
| prefix     | 限定返回的对象名必须带有prefix前缀。                                                                                                                                                                                                                                                       | ListObjectsRequest.setPrefix     |
| marker     | 列举对象的起始位置，返回的对象列表将是对象名按照字典序排序后该参数以后的所有对象。                                                                                                                                                                                                                                   | ListObjectsRequest.setMarker     |
| maxKeys    | 列举对象的最大数目，取值范围为1\~1000，当超出范围时，按照默认的1000进行处理。                                                                                                                                                                                                                                | ListObjectsRequest.setMaxKeys    |
| delimiter  | 用于对对象名进行分组的字符。对于对象名中包含delimiter的对象，其对象名（如果请求中指定了prefix，则此处的对象名需要去掉prefix）中从首字符至第一个delimiter之间的字符串将作为一个分组并作为commonPrefix返回。 对于并行文件系统，不携带此参数时默认列举是递归列举此目录下所有内容，会列举子目录。在大数据场景下（目录层级深、目录下文件多）的列举，建议设置\[delimiter="/"\]，只列举当前目录下的内容，不列举子目录，提高列举效率。 | ListObjectsRequest.setDelimiter  |
   
#### 简单列举
以下代码展示如何简单列举对象，最多返回1000个对象：
```
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
String ak = System.getenv("ACCESS_KEY_ID");
String sk = System.getenv("SECRET_ACCESS_KEY_ID");
String endPoint = "https://your-endpoint";
// 创建ObsClient实例
final ObsClient obsClient = new ObsClient(ak, sk, endPoint);
ObjectListing result = obsClient.listObjects("bucketname");
for(ObsObject obsObject : result.getObjects()){
    Log.i("ListObjects", "\t" + obsObject.getObjectKey());
    Log.i("ListObjects","\t" + obsObject.getOwner());
}
```
![](https://support.huaweicloud.com/sdk-android-devg-obs/public_sys-resources/note_3.0-zh-cn.png)
- 每次至多返回1000个对象，如果指定桶包含的对象数量大于1000，则返回结果中ObjectListing.isTruncated为true表明本次没有返回全部对象，并可通过ObjectListing.getNextMarker获取下次列举的起始位置。
- 如果想获取指定桶包含的所有对象，可以采用分页列举的方式。
 
#### 指定数目列举
以下代码展示如何指定数目列举对象：
```
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
String ak = System.getenv("ACCESS_KEY_ID");
String sk = System.getenv("SECRET_ACCESS_KEY_ID");
String endPoint = "https://your-endpoint";
// 创建ObsClient实例
final ObsClient obsClient = new ObsClient(ak, sk, endPoint);
ListObjectsRequest request = new ListObjectsRequest("bucketname");
// 只列举100个对象
request.setMaxKeys(100);
ObjectListing result = obsClient.listObjects(request);
for(ObsObject obsObject : result.getObjects()){
    Log.i("ListObjects","\t" + obsObject.getObjectKey());
    Log.i("ListObjects","\t" + obsObject.getOwner());
}
```
#### 指定前缀列举
以下代码展示如何指定前缀列举对象：
```
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
String ak = System.getenv("ACCESS_KEY_ID");
String sk = System.getenv("SECRET_ACCESS_KEY_ID");
String endPoint = "https://your-endpoint";
// 创建ObsClient实例
final ObsClient obsClient = new ObsClient(ak, sk, endPoint);
ListObjectsRequest request = new ListObjectsRequest("bucketname");
// 设置列举带有prefix前缀的100个对象
request.setMaxKeys(100);
request.setPrefix("prefix");
ObjectListing result = obsClient.listObjects(request);
for(ObsObject obsObject : result.getObjects()){
    Log.i("ListObjects","\t" + obsObject.getObjectKey());
    Log.i("ListObjects","\t" + obsObject.getOwner());
}
```
#### 指定起始位置列举
以下代码展示如何指定起始位置列举对象：
```
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
String ak = System.getenv("ACCESS_KEY_ID");
String sk = System.getenv("SECRET_ACCESS_KEY_ID");
String endPoint = "https://your-endpoint";
// 创建ObsClient实例
final ObsClient obsClient = new ObsClient(ak, sk, endPoint);
ListObjectsRequest request = new ListObjectsRequest("bucketname");
// 设置列举对象名字典序在"test"之后的100个对象
request.setMaxKeys(100);
request.setMarker("test");
ObjectListing result = obsClient.listObjects(request);
for(ObsObject obsObject : result.getObjects()){
    Log.i("ListObjects","\t" + obsObject.getObjectKey());
    Log.i("ListObjects","\t" + obsObject.getOwner());
}
```
#### 分页列举全部对象
以下代码展示分页列举全部对象：
```
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
String ak = System.getenv("ACCESS_KEY_ID");
String sk = System.getenv("SECRET_ACCESS_KEY_ID");
String endPoint = "https://your-endpoint";
// 创建ObsClient实例
final ObsClient obsClient = new ObsClient(ak, sk, endPoint);
ListObjectsRequest request = new ListObjectsRequest("bucketname");
// 设置每页100个对象
request.setMaxKeys(100);
ObjectListing result;
do{
    result = obsClient.listObjects(request);
    for(ObsObject obsObject : result.getObjects()){
        Log.i("ListObjects","\t" + obsObject.getObjectKey());
        Log.i("ListObjects","\t" + obsObject.getOwner());
    }
    
    request.setMarker(result.getNextMarker());
}while(result.isTruncated());
```
#### 列举文件夹中的所有对象
OBS本身是没有文件夹的概念的，桶中存储的元素只有对象。文件夹对象实际上是一个大小为0且对象名以"/"结尾的对象，将这个文件夹对象名作为前缀，即可模拟列举文件夹中对象的功能。以下代码展示如何列举文件夹中的对象：
```
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
String ak = System.getenv("ACCESS_KEY_ID");
String sk = System.getenv("SECRET_ACCESS_KEY_ID");
String endPoint = "https://your-endpoint";
// 创建ObsClient实例
ObsClient obsClient = new ObsClient(ak, sk, endPoint);
ListObjectsRequest request = new ListObjectsRequest("bucketname");
// 设置文件夹对象名"dir/"为前缀
request.setPrefix("dir/");
request.setMaxKeys(1000);
ObjectListing result;
do{
    result = obsClient.listObjects(request);
    for (ObsObject obsObject : result.getObjects())
    {
        Log.i("ListObjects","\t" + obsObject.getObjectKey());
        Log.i("ListObjects","\t" + obsObject.getOwner());
    }
    request.setMarker(result.getNextMarker());
}while(result.isTruncated());
```
#### 按文件夹分组列举所有对象
以下代码展示如何按文件夹分组，列举桶内所有对象：
```
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险，建议在配置文件或者环境变量中密文存放，使用时解密，确保安全；本示例以ak和sk保存在环境变量中为例，运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK，获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
String ak = System.getenv("ACCESS_KEY_ID");
String sk = System.getenv("SECRET_ACCESS_KEY_ID");
String endPoint = "https://your-endpoint";
// 创建ObsClient实例
final ObsClient obsClient = new ObsClient(ak, sk, endPoint);
ListObjectsRequest request = new ListObjectsRequest("bucketname");
request.setMaxKeys(1000);
// 设置文件夹分隔符"/"
request.setDelimiter("/");
ObjectListing result = obsClient.listObjects(request);
Log.i("ListObjects", "Objects in the root directory:");
for(ObsObject obsObject : result.getObjects()){
    Log.i("ListObjects","\t" + obsObject.getObjectKey());
    Log.i("ListObjects","\t" + obsObject.getOwner());
}
listObjectsByPrefix(obsClient, request, result);
```
递归列出子文件夹中对象的函数*listObjectsByPrefix*的示例代码如下：
```
static void listObjectsByPrefix(ObsClient obsClient, ListObjectsRequest request, ObjectListing result) throws ObsException
{
      for(String prefix : result.getCommonPrefixes()){
          Log.i("ListObjects", "Objects in folder [" + prefix + "]:");
          request.setPrefix(prefix);
          result  = obsClient.listObjects(request);
          for(ObsObject obsObject : result.getObjects()){
              Log.i("ListObjects","\t" + obsObject.getObjectKey());
              Log.i("ListObjects","\t" + obsObject.getOwner());
          }
          listObjectsByPrefix(obsClient, request, result);
      }
}
```
![](https://support.huaweicloud.com/sdk-android-devg-obs/public_sys-resources/note_3.0-zh-cn.png)
- 以上代码示例没有考虑文件夹中对象数超过1000个的情况。
- 由于是需要列举出文件夹中的对象和子文件夹，且文件夹对象总是以"/"结尾，因此delimiter总是为"/"。
- 每次递归的返回结果中ObjectListing.getObjects包含的是文件夹中的对象；ObjectListing.getCommonPrefixes包含的是文件夹的子文件夹。
 
