更新时间:2026-09-10 GMT+08:00
SDK如何进行批量操作?
目前SDK暂未提供此类接口,您需要自己封装批量上传、下载、复制或恢复对象的业务代码。步骤如下:
- 调用listObjects列举所有待下载、复制或恢复的对象,具体代码示例请参见列举对象,批量上传需要遍历本地待上传文件。
- 对列举出的对象调用单个对象的上传(上传对象)、下载(下载对象)、复制(复制对象)或恢复(恢复归档对象)接口。
您可以使用多线程并发执行上传/下载/复制/恢复操作,以提高效率。
代码示例一:批量上传
以下代码展示了批量上传对象。
import android.util.Log;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.PutObjectResult;
import java.io.File;
public class PutObjectDemo {
private static final String TAG = "PutObjectDemo";
public void execute() {
new Thread(new Runnable() {
@Override
public void run() {
// 认证用的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");
// endpoint填写桶所在的endpoint, 此处以华北-北京四为例,其他地区请按实际情况填写。
String endPoint = "https://your-endpoint";
// 创建ObsClient实例
ObsClient obsClient = new ObsClient(ak, sk, endPoint);
try {
String bucketName = "examplebucket";
// 定义桶内对象的前缀
String objectPre = "object/";
// 待上传的文件夹
// Android 10及以上建议使用 context.getExternalFilesDir(null) 获取应用专属外部存储目录
// 此处使用硬编码路径仅作示例,实际使用时请替换为应用可访问的路径
String localDirPath = "/sdcard/Download/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(TAG, "Upload succeeded: " + objectKey);
succeedCount++;
} catch (Exception e) {
Log.e(TAG, "batch upload failed: " + e.getMessage());
failCount++;
}
}
}
Log.i(TAG, "Batch upload completed. Succeed: " + succeedCount + ", Failed: " + failCount);
}
}
} catch (ObsException e) {
Log.e(TAG, "execute failed");
Log.e(TAG, "HTTP Code:" + e.getResponseCode());
Log.e(TAG, "Error Code:" + e.getErrorCode());
Log.e(TAG, "Error Message:" + e.getErrorMessage());
Log.e(TAG, "Request ID:" + e.getErrorRequestId());
Log.e(TAG, "Host ID:" + e.getErrorHostId());
} catch (Exception e) {
Log.e(TAG, "execute failed");
Log.e(TAG, e.getMessage());
} finally {
try {
obsClient.close();
} catch (Exception e) {
// 忽略关闭异常
}
}
}
}).start();
}
}
- 如果本地文件数量较多或文件较大,建议使用多线程并发执行上传操作,以提高效率。
- 如需上传子文件夹中的文件,需递归遍历目录结构。
- 如果待上传文件较大,可以使用断点续传上传接口(uploadFile)替换上传对象接口(putObject)。
代码示例二:批量下载
以下代码展示了批量下载对象。
import java.io.File;
import android.util.Log;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.ListObjectsRequest;
import com.obs.services.model.ObjectListing;
import com.obs.services.model.ObsObject;
import com.obs.services.model.DownloadFileRequest;
public class ListObjectsDemo {
private static final String TAG = "ListObjectsDemo";
public void execute() {
new Thread(new Runnable() {
@Override
public void run() {
// 认证用的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");
// endpoint填写桶所在的endpoint, 此处以华北-北京四为例,其他地区请按实际情况填写。
String endPoint = "https://your-endpoint";
// 创建ObsClient实例
ObsClient obsClient = new ObsClient(ak, sk, endPoint);
try {
String bucketName = "examplebucket";
String objectPre = "object/";
// 本地下载目录
// Android 10及以上建议使用 context.getExternalFilesDir(null) 获取应用专属外部存储目录
// 此处使用硬编码路径仅作示例,实际使用时请替换为应用可访问的路径
String localDownloadDir = "/sdcard/Download/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());
// 确保本地目录存在,避免因目录不存在导致下载失败
File localFile = new File(localFilePath);
File parentDir = localFile.getParentFile();
if (parentDir != null && !parentDir.exists()) {
parentDir.mkdirs();
}
DownloadFileRequest downloadRequest = new DownloadFileRequest(bucketName, objectKey);
downloadRequest.setDownloadFile(localFilePath);
obsClient.downloadFile(downloadRequest);
Log.i(TAG, "Downloaded: " + objectKey);
}
Log.i(TAG, "Batch download completed");
} catch (ObsException e) {
Log.e(TAG, "execute failed");
Log.e(TAG, "HTTP Code:" + e.getResponseCode());
Log.e(TAG, "Error Code:" + e.getErrorCode());
Log.e(TAG, "Error Message:" + e.getErrorMessage());
Log.e(TAG, "Request ID:" + e.getErrorRequestId());
Log.e(TAG, "Host ID:" + e.getErrorHostId());
} catch (Exception e) {
Log.e(TAG, "execute failed");
Log.e(TAG, e.getMessage());
} finally {
try {
obsClient.close();
} catch (Exception e) {
// 忽略关闭异常
}
}
}
}).start();
}
}
- 您可以使用多线程并发执行下载操作,以提高效率。
- 如果桶内对象数量较多,需要使用分页列举的方式获取全部对象,具体请参见 列举对象章节。
代码示例三:批量复制
以下代码展示了批量复制对象。
import android.util.Log;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.ListObjectsRequest;
import com.obs.services.model.ObjectListing;
import com.obs.services.model.ObsObject;
import com.obs.services.model.CopyObjectRequest;
public class ListObjectsDemo {
private static final String TAG = "ListObjectsDemo";
public void execute() {
new Thread(new Runnable() {
@Override
public void run() {
// 认证用的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");
// endpoint填写桶所在的endpoint, 此处以华北-北京四为例,其他地区请按实际情况填写。
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(TAG, "Copied: " + objectKey);
}
Log.i(TAG, "Batch copy completed");
} catch (ObsException e) {
Log.e(TAG, "execute failed");
Log.e(TAG, "HTTP Code:" + e.getResponseCode());
Log.e(TAG, "Error Code:" + e.getErrorCode());
Log.e(TAG, "Error Message:" + e.getErrorMessage());
Log.e(TAG, "Request ID:" + e.getErrorRequestId());
Log.e(TAG, "Host ID:" + e.getErrorHostId());
} catch (Exception e) {
Log.e(TAG, "execute failed");
Log.e(TAG, e.getMessage());
} finally {
try {
obsClient.close();
} catch (Exception e) {
// 忽略关闭异常
}
}
}
}).start();
}
}
- 如果桶内对象数量较多,需要使用分页列举的方式获取全部对象,具体请参见 列举对象章节。
代码示例四:批量恢复
以下代码展示了按前缀批量恢复对象。
import android.util.Log;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.ListObjectsRequest;
import com.obs.services.model.ObjectListing;
import com.obs.services.model.ObsObject;
import com.obs.services.model.RestoreObjectRequest;
import com.obs.services.model.RestoreTierEnum;
public class ListObjectsDemo {
private static final String TAG = "ListObjectsDemo";
public void execute() {
new Thread(new Runnable() {
@Override
public void run() {
// 认证用的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");
// endpoint填写桶所在的endpoint, 此处以华北-北京四为例,其他地区请按实际情况填写。
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(TAG, "Restore succeeded: " + objectKey);
succeedCount++;
} catch (Exception e) {
Log.e(TAG, "batch restore failed: " + e.getMessage());
failCount++;
}
}
Log.i(TAG, "Batch restore completed. Succeed: " + succeedCount + ", Failed: " + failCount);
} catch (ObsException e) {
Log.e(TAG, "execute failed");
Log.e(TAG, "HTTP Code:" + e.getResponseCode());
Log.e(TAG, "Error Code:" + e.getErrorCode());
Log.e(TAG, "Error Message:" + e.getErrorMessage());
Log.e(TAG, "Request ID:" + e.getErrorRequestId());
Log.e(TAG, "Host ID:" + e.getErrorHostId());
} catch (Exception e) {
Log.e(TAG, "execute failed");
Log.e(TAG, e.getMessage());
} finally {
try {
obsClient.close();
} catch (Exception e) {
// 忽略关闭异常
}
}
}
}).start();
}
} 以下代码展示了按对象名列表批量恢复对象。
import android.util.Log;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.RestoreObjectRequest;
import com.obs.services.model.RestoreTierEnum;
public class RestoreObjectDemo {
private static final String TAG = "RestoreObjectDemo";
public void execute() {
new Thread(new Runnable() {
@Override
public void run() {
// 认证用的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");
// endpoint填写桶所在的endpoint, 此处以华北-北京四为例,其他地区请按实际情况填写。
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(TAG, "Restore succeeded: " + objectKey);
succeedCount++;
} catch (Exception e) {
Log.e(TAG, "batch restore failed: " + e.getMessage());
failCount++;
}
}
Log.i(TAG, "Batch restore completed. Succeed: " + succeedCount + ", Failed: " + failCount);
} catch (ObsException e) {
Log.e(TAG, "execute failed");
Log.e(TAG, "HTTP Code:" + e.getResponseCode());
Log.e(TAG, "Error Code:" + e.getErrorCode());
Log.e(TAG, "Error Message:" + e.getErrorMessage());
Log.e(TAG, "Request ID:" + e.getErrorRequestId());
Log.e(TAG, "Host ID:" + e.getErrorHostId());
} catch (Exception e) {
Log.e(TAG, "execute failed");
Log.e(TAG, e.getMessage());
} finally {
try {
obsClient.close();
} catch (Exception e) {
// 忽略关闭异常
}
}
}
}).start();
}
}
- 如果桶内对象数量较多,需要使用分页列举的方式获取全部对象,具体请参见 列举对象章节。
父主题: 常见问题