开发者社区 问答 正文

Java-SDK之如何实现上传文件(四)?


上传分片




初始化一个Multipart Upload之后,可以根据指定的Object名和Upload ID来分片(Part)上传数据。每一个上传的Part都有一个标识它的号码——分片号(part number,范围是1~10,000)。对于同一个Upload ID,该分片号不但唯一标识这一块数据,也标识了这块数据在整个文件内的相对位置。如果你用同一个分片号码,上传了新的数据,那么OSS上已有的这个分片的数据将被覆盖。除了最后一块Part以外,其他的part最小为100KB;最后一块Part没有大小限制。每个分片不需要按顺序上传,甚至可以在不同进程、不同机器上上传,OSS会按照分片号排序组成大文件。
调用OSSClient.uploadPart上传分片:

  1. List<PartETag> partETags = new ArrayList<PartETag>();
  2. InputStream instream = new FileInputStream(new File("<localFile>"));
  3. UploadPartRequest uploadPartRequest = new UploadPartRequest();
  4. uploadPartRequest.setBucketName(bucketName);
  5. uploadPartRequest.setKey(key);
  6. uploadPartRequest.setUploadId(uploadId);
  7. uploadPartRequest.setInputStream(instream);
  8. // 设置分片大小,除最后一个分片外,其它分片要大于100KB
  9. uploadPartRequest.setPartSize(100 * 1024);
  10. // 设置分片号,范围是1~10000,
  11. uploadPartRequest.setPartNumber(1);
  12. UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
  13. 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完成分片上传:
  1. Collections.sort(partETags, new Comparator<PartETag>() {
  2.     @Override
  3.     public int compare(PartETag p1, PartETag p2) {
  4.         return p1.getPartNumber() - p2.getPartNumber();
  5.     }
  6. });
  7. CompleteMultipartUploadRequest completeMultipartUploadRequest =
  8.         new CompleteMultipartUploadRequest(bucketName, key, uploadId, partETags);
  9. ossClient.completeMultipartUpload(completeMultipartUploadRequest);

注意:
  • 上面代码中的 partETags 就是进行分片上传中保存的partETag的列表,它必须是按分片号升序排序;
  • 分片可以是不连续的。




取消分片上传事件




该接口可以根据Upload ID中止对应的Multipart Upload事件。当一个Multipart Upload事件被中止后,就不能再使用这个Upload ID做任何操作,已经上传的Part数据也会被删除。
调用OSSClient.abortMultipartUpload取消分片上传事件:
  1. // endpoint以杭州为例,其它region请按实际情况填写
  2. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
  3. // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建
  4. String accessKeyId = "<yourAccessKeyId>";
  5. String accessKeySecret = "<yourAccessKeySecret>";
  6. // 创建OSSClient实例
  7. OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
  8. // 上传字符串
  9. String content = "Hello OSS";
  10. ossClient.putObject("<yourBucketName>", "<yourKey>", new ByteArrayInputStream(content.getBytes()));
  11. // 取消分片上传,其中uploadId来自于initiateMultipartUpload
  12. AbortMultipartUploadRequest abortMultipartUploadRequest =
  13.         new AbortMultipartUploadRequest("<yourBucketName>", "<yourKey>", "<uploadId>");
  14. ossClient.abortMultipartUpload(abortMultipartUploadRequest);
  15. // 关闭client
  16. ossClient.shutdown();









展开
收起
青衫无名 2017-10-18 10:46:16 2099 分享 版权
0 条回答
写回答
取消 提交回答