上传分片
初始化一个Multipart Upload之后,可以根据指定的Object名和Upload ID来分片(Part)上传数据。每一个上传的Part都有一个标识它的号码——分片号(part number,范围是1~10,000)。对于同一个Upload ID,该分片号不但唯一标识这一块数据,也标识了这块数据在整个文件内的相对位置。如果你用同一个分片号码,上传了新的数据,那么OSS上已有的这个分片的数据将被覆盖。除了最后一块Part以外,其他的part最小为100KB;最后一块Part没有大小限制。每个分片不需要按顺序上传,甚至可以在不同进程、不同机器上上传,OSS会按照分片号排序组成大文件。
调用OSSClient.uploadPart上传分片:
- List<PartETag> partETags = new ArrayList<PartETag>();
- InputStream instream = new FileInputStream(new File("<localFile>"));
- UploadPartRequest uploadPartRequest = new UploadPartRequest();
- uploadPartRequest.setBucketName(bucketName);
- uploadPartRequest.setKey(key);
- uploadPartRequest.setUploadId(uploadId);
- uploadPartRequest.setInputStream(instream);
- // 设置分片大小,除最后一个分片外,其它分片要大于100KB
- uploadPartRequest.setPartSize(100 * 1024);
- // 设置分片号,范围是1~10000,
- uploadPartRequest.setPartNumber(1);
- UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
- partETags.add(uploadPartResult.getPartETag());
注意:
- UploadPart 方法要求除最后一个Part以外,其他的Part大小都要大于100KB。但是Upload Part接口并不会立即校验上传Part的大小(因为不知道是否为最后一块);只有当Complete Multipart Upload的时候才会校验。
- OSS会将服务器端收到Part数据的MD5值放在ETag头内返回给用户。
- 为了保证数据在网络传输过程中不出现错误,SDK会自动设置Content-MD5,OSS会计算上传数据的MD5值与SDK计算的MD5值比较,如果不一致返回InvalidDigest错误码。
- Part号码的范围是1~10000。如果超出这个范围,OSS将返回InvalidArgument的错误码。
- 每次上传part时都要把流定位到此次上传块开头所对应的位置。
- 每次上传part之后,OSS的返回结果会包含一个 PartETag 对象,他是上传块的ETag与块编号(PartNumber)的组合,
- 在后续完成分片上传的步骤中会用到它,因此我们需要将其保存起来。一般来讲我们将这些 PartETag 对象保存到List中。
完成分片上传
所有分片上传完成后,需要调用Complete Multipart Upload来完成整个文件的Multipart Upload。在执行该操作时,需要提供所有有效的分片列表(包括分片号和分片ETAG);OSS收到提交的分片列表后,会逐一验证每个分片的有效性。当所有的数据Part验证通过后,OSS将把这些分片组合成一个完整的Object。
调用OSSClient.completeMultipartUpload完成分片上传:
- Collections.sort(partETags, new Comparator<PartETag>() {
- @Override
- public int compare(PartETag p1, PartETag p2) {
- return p1.getPartNumber() - p2.getPartNumber();
- }
- });
- CompleteMultipartUploadRequest completeMultipartUploadRequest =
- new CompleteMultipartUploadRequest(bucketName, key, uploadId, partETags);
- ossClient.completeMultipartUpload(completeMultipartUploadRequest);
注意:
- 上面代码中的 partETags 就是进行分片上传中保存的partETag的列表,它必须是按分片号升序排序;
- 分片可以是不连续的。
取消分片上传事件
该接口可以根据Upload ID中止对应的Multipart Upload事件。当一个Multipart Upload事件被中止后,就不能再使用这个Upload ID做任何操作,已经上传的Part数据也会被删除。
调用OSSClient.abortMultipartUpload取消分片上传事件:
- // endpoint以杭州为例,其它region请按实际情况填写
- String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
- // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
- String accessKeyId = "<yourAccessKeyId>";
- String accessKeySecret = "<yourAccessKeySecret>";
- // 创建OSSClient实例
- OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
- // 上传字符串
- String content = "Hello OSS";
- ossClient.putObject("<yourBucketName>", "<yourKey>", new ByteArrayInputStream(content.getBytes()));
- // 取消分片上传,其中uploadId来自于initiateMultipartUpload
- AbortMultipartUploadRequest abortMultipartUploadRequest =
- new AbortMultipartUploadRequest("<yourBucketName>", "<yourKey>", "<uploadId>");
- ossClient.abortMultipartUpload(abortMultipartUploadRequest);
- // 关闭client
- ossClient.shutdown();