更新时间:2024-12-03 GMT+08:00
分段复制
分段复制是分段上传的一种特殊情况,即分段上传任务中的段通过复制OBS指定桶中现有对象(或对象的一部分)来实现。您可以通过ObsClient.copyPart来复制段。
本示例用于分段复制桶名为“sourcebucketname”里的“sourceobjectname”对象到桶名为“destbucketname”里的“destobjectname”对象。
代码示例如下所示:
// 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;本示例以ak和sk保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量ACCESS_KEY_ID和SECRET_ACCESS_KEY_ID。 // 您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/intl/zh-cn/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"; final String destBucketName = "destbucketname"; final String destObjectKey = "destobjectname"; final String sourceBucketName = "sourcebucketname"; final String sourceObjectKey = "sourceobjectname"; // 创建ObsClient实例 final ObsClient obsClient = new ObsClient(ak, sk, endPoint); // 初始化线程池 ExecutorService executorService = Executors.newFixedThreadPool(20); // 初始化分段上传任务 InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(destBucketName, destObjectKey); InitiateMultipartUploadResult result = obsClient.initiateMultipartUpload(request); final String uploadId = result.getUploadId(); Log.i("CopyPart","\t"+ uploadId + "\n"); // 获取大对象信息 ObjectMetadata metadata = obsClient.getObjectMetadata(sourceBucketName, sourceObjectKey); // 每段复制100MB long partSize = 100 * 1024 * 1024L; long objectSize = metadata.getContentLength(); // 计算需要复制的段数 long partCount = objectSize % partSize == 0 ? objectSize / partSize : objectSize / partSize + 1; final List<PartEtag> partEtags = Collections.synchronizedList(new ArrayList<PartEtag>()); // 执行并发复制段 for (int i = 0; i < partCount; i++) { // 复制段起始位置 final long rangeStart = i * partSize; // 复制段结束位置 final long rangeEnd = (i + 1 == partCount) ? objectSize - 1 : rangeStart + partSize - 1; // 分段号 final int partNumber = i + 1; executorService.execute(new Runnable() { @Override public void run() { CopyPartRequest request = new CopyPartRequest(); request.setUploadId(uploadId); request.setSourceBucketName(sourceBucketName); request.setSourceObjectKey(sourceObjectKey); request.setDestinationBucketName(destBucketName); request.setDestinationObjectKey(destObjectKey); request.setByteRangeStart(rangeStart); request.setByteRangeEnd(rangeEnd); request.setPartNumber(partNumber); CopyPartResult result; try { result = obsClient.copyPart(request); Log.i("CopyPart","Part#" + partNumber + " done\n"); partEtags.add(new PartEtag(result.getEtag(), result.getPartNumber())); } catch (ObsException e) { Log.e("CopyPart", e.getMessage(), e); } } }); } // 等待复制完成 executorService.shutdown(); while (!executorService.isTerminated()) { try { executorService.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { Log.e("CopyPart", e.getMessage(), e); } } // 合并段 CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(destBucketName, destObjectKey, uploadId, partEtags); obsClient.completeMultipartUpload(completeMultipartUploadRequest);
复制段时,使用PartNumber参数指定分段号;使用UploadId参数指定分段上传任务的全局唯一标识;使用CopySource参数指定复制时的源对象信息;使用CopySourceRange参数指定待复制的源对象的字节范围。
父主题: 上传对象