文档首页/ 对象存储服务 OBS/ SDK参考/ Android/ 常见问题/ SDK如何进行批量操作?
更新时间:2026-08-14 GMT+08:00

SDK如何进行批量操作?

目前SDK暂未提供此类接口,您需要自己封装批量上传、下载、复制或恢复对象的业务代码。步骤如下:

  1. 调用listObjects列举所有待下载、复制或恢复的对象,具体代码示例请参见列举对象,批量上传需要遍历本地待上传文件。
  2. 对列举出的对象调用单个对象的上传(上传对象)、下载(下载对象)、复制(复制对象)或恢复(恢复归档对象)接口。

您可以使用多线程并发执行上传/下载/复制/恢复操作,以提高效率。

代码示例一:批量上传

以下代码展示了批量上传对象。

// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;
// 本示例以ak和sk保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK
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);

try {
    String bucketName = "examplebucket";
    // 定义桶内对象的前缀
    String objectPre = "object/";
    // 待上传的文件夹
    String localDirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/localDirPath";

    // 遍历本地文件夹,逐个上传文件
    File localDir = new File(localDirPath);
    if (localDir != null && localDir.isDirectory()) {
        File[] files = localDir.listFiles();
        if (files != null) {
            int succeedCount = 0;
            int failCount = 0;
            for (File file : files) {
                if (file.isFile()) {
                    try {
                        String objectKey = objectPre + file.getName();
                        PutObjectResult result = obsClient.putObject(bucketName, objectKey, file);
                        Log.i("BatchUpload", "Upload succeeded: " + objectKey);
                        succeedCount++;
                    } catch (ObsException e) {
                        Log.e("BatchUpload", "Upload failed: " + file.getName()
                                + ", Error Code: " + e.getErrorCode()
                                + ", Error Message: " + e.getErrorMessage());
                        failCount++;
                    }
                }
            }
            Log.i("BatchUpload", "Batch upload completed. Succeed: " + succeedCount + ", Failed: " + failCount);
        }
    }
} catch (ObsException e) {
    Log.e("BatchUpload", "Response Code: " + e.getResponseCode());
    Log.e("BatchUpload", "Error Message: " + e.getErrorMessage());
    Log.e("BatchUpload", "Error Code:    " + e.getErrorCode());
    Log.e("BatchUpload", "Request ID:    " + e.getErrorRequestId());
    Log.e("BatchUpload", "Host ID:       " + e.getErrorHostId());
} catch (Exception e) {
    Log.e("BatchUpload", "batch upload failed: " + e.getMessage());
}
  • 网络操作必须在子线程中执行,请勿在主线程(UI线程)中调用上述代码,否则会抛出 NetworkOnMainThreadException 异常。
  • 如果本地文件数量较多或文件较大,建议使用多线程并发执行上传操作,以提高效率。
  • 如需上传子文件夹中的文件,需递归遍历目录结构。
  • 如果待上传文件较大,可以使用断点续传上传接口(uploadFile)替换上传对象接口(putObject)。

代码示例二:批量下载

以下代码展示了批量下载对象。

// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;
// 本示例以ak和sk保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK
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);

try {
    String bucketName = "examplebucket";
    String objectPre = "object/";
    // 本地下载目录
    String localDownloadDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/download";

    // 1. 列举桶内指定前缀的所有对象
    ListObjectsRequest listRequest = new ListObjectsRequest(bucketName);
    listRequest.setPrefix(objectPre);
    ObjectListing result = obsClient.listObjects(listRequest);

    // 2. 逐个下载对象
    for (ObsObject obsObject : result.getObjects()) {
        String objectKey = obsObject.getObjectKey();
        // 跳过文件夹对象(以"/"结尾的对象)
        if (objectKey.endsWith("/")) {
            continue;
        }
        // 生成本地文件路径
        String localFilePath = localDownloadDir + "/" + objectKey.substring(objectPre.length());
        DownloadFileRequest downloadRequest = new DownloadFileRequest(bucketName, objectKey);
        downloadRequest.setDownloadFile(localFilePath);
        obsClient.downloadFile(downloadRequest);
        Log.i("BatchDownload", "Downloaded: " + objectKey);
    }
    Log.i("BatchDownload", "Batch download completed");
} catch (ObsException e) {
    Log.e("BatchDownload", "Response Code: " + e.getResponseCode());
    Log.e("BatchDownload", "Error Message: " + e.getErrorMessage());
    Log.e("BatchDownload", "Error Code:    " + e.getErrorCode());
    Log.e("BatchDownload", "Request ID:    " + e.getErrorRequestId());
    Log.e("BatchDownload", "Host ID:       " + e.getErrorHostId());
} catch (Exception e) {
    Log.e("BatchDownload", "Batch download failed: " + e.getMessage());
}
  • 网络操作必须在子线程中执行,请勿在主线程(UI线程)中调用上述代码,否则会抛出 NetworkOnMainThreadException 异常。
  • 您可以使用多线程并发执行下载操作,以提高效率。
  • 如果桶内对象数量较多,需要使用分页列举的方式获取全部对象,具体请参见 列举对象章节。

代码示例三:批量复制

以下代码展示了批量复制对象。

// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;
// 本示例以ak和sk保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK
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);

try {
    String sourceBucketName = "examplebucket";
    String destBucketName = "destbucket";
    String objectPre = "object/";

    // 1. 列举源桶内指定前缀的所有对象
    ListObjectsRequest listRequest = new ListObjectsRequest(sourceBucketName);
    listRequest.setPrefix(objectPre);
    ObjectListing result = obsClient.listObjects(listRequest);

    // 2. 逐个复制对象
    for (ObsObject obsObject : result.getObjects()) {
        String objectKey = obsObject.getObjectKey();
        // 跳过文件夹对象
        if (objectKey.endsWith("/")) {
            continue;
        }
        CopyObjectRequest copyRequest = new CopyObjectRequest(sourceBucketName, objectKey, destBucketName, objectKey);
        obsClient.copyObject(copyRequest);
        Log.i("BatchCopy", "Copied: " + objectKey);
    }
    Log.i("BatchCopy", "Batch copy completed");
} catch (ObsException e) {
    Log.e("BatchCopy", "Response Code: " + e.getResponseCode());
    Log.e("BatchCopy", "Error Message: " + e.getErrorMessage());
    Log.e("BatchCopy", "Error Code:    " + e.getErrorCode());
    Log.e("BatchCopy", "Request ID:    " + e.getErrorRequestId());
    Log.e("BatchCopy", "Host ID:       " + e.getErrorHostId());
} catch (Exception e) {
    Log.e("BatchCopy", "Batch copy failed: " + e.getMessage());
}
  • 网络操作必须在子线程中执行,请勿在主线程(UI线程)中调用上述代码,否则会抛出 NetworkOnMainThreadException 异常。
  • 如果桶内对象数量较多,需要使用分页列举的方式获取全部对象,具体请参见 列举对象章节。

代码示例四:批量恢复

以下代码展示了按前缀批量恢复对象。

// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;
// 本示例以ak和sk保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK
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);

try {
    String bucketName = "examplebucket";
    String objectPre = "object/";

    // 1. 列举桶内指定前缀的所有对象
    ListObjectsRequest listRequest = new ListObjectsRequest(bucketName);
    listRequest.setPrefix(objectPre);
    ObjectListing listing = obsClient.listObjects(listRequest);

    // 2. 逐个恢复归档或深度归档存储对象
    int succeedCount = 0;
    int failCount = 0;
    for (ObsObject obsObject : listing.getObjects()) {
        String objectKey = obsObject.getObjectKey();
        // 跳过文件夹对象(以"/"结尾的对象)
        if (objectKey.endsWith("/")) {
            continue;
        }
        try {
            RestoreObjectRequest request = new RestoreObjectRequest();
            request.setBucketName(bucketName);
            request.setObjectKey(objectKey);
            // 设置恢复对象的保存天数
            request.setRestoreDays(7);
            // 设置恢复选项为标准恢复
            request.setTier(RestoreTierEnum.STANDARD);

            obsClient.restoreObject(request);
            Log.i("BatchRestore", "Restore succeeded: " + objectKey);
            succeedCount++;
        } catch (ObsException e) {
            Log.e("BatchRestore", "Restore failed: " + objectKey
                    + ", Error Code: " + e.getErrorCode()
                    + ", Error Message: " + e.getErrorMessage());
            failCount++;
        }
    }
    Log.i("BatchRestore", "Batch restore completed. Succeed: " + succeedCount + ", Failed: " + failCount);
} catch (ObsException e) {
    Log.e("BatchRestore", "Response Code: " + e.getResponseCode());
    Log.e("BatchRestore", "Error Message: " + e.getErrorMessage());
    Log.e("BatchRestore", "Error Code:    " + e.getErrorCode());
    Log.e("BatchRestore", "Request ID:    " + e.getErrorRequestId());
    Log.e("BatchRestore", "Host ID:       " + e.getErrorHostId());
} catch (Exception e) {
    Log.e("BatchRestore", "batch restore failed: " + e.getMessage());
}

以下代码展示了按对象名列表批量恢复对象。

// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;
// 本示例以ak和sk保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。
// 您可以登录访问管理控制台获取访问密钥AK/SK
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);

try {
    String bucketName = "examplebucket";
    // 待恢复的对象名列表
    String[] objectKeys = {"objectname1", "objectname2", "objectname3"};

    int succeedCount = 0;
    int failCount = 0;
    for (String objectKey : objectKeys) {
        try {
            RestoreObjectRequest request = new RestoreObjectRequest();
            request.setBucketName(bucketName);
            request.setObjectKey(objectKey);
            // 设置恢复对象的保存天数
            request.setRestoreDays(1);
            // 设置恢复选项为快速恢复
            request.setTier(RestoreTierEnum.EXPEDITED);

            obsClient.restoreObject(request);
            Log.i("BatchRestore", "Restore succeeded: " + objectKey);
            succeedCount++;
        } catch (ObsException e) {
            Log.e("BatchRestore", "Restore failed: " + objectKey
                    + ", Error Code: " + e.getErrorCode()
                    + ", Error Message: " + e.getErrorMessage());
            failCount++;
        }
    }
    Log.i("BatchRestore", "Batch restore completed. Succeed: " + succeedCount + ", Failed: " + failCount);
} catch (Exception e) {
    Log.e("BatchRestore", "batch restore failed: " + e.getMessage());
}
  • 网络操作必须在子线程中执行,请勿在主线程(UI线程)中调用上述代码,否则会抛出 NetworkOnMainThreadException 异常。
  • 如果桶内对象数量较多,需要使用分页列举的方式获取全部对象,具体请参见 列举对象章节。