分片上传
更新时间: 2020-04-24
目录
本节介绍分片上传的相关功能。
分片上传(Multipart Upload)分为以下三个步骤:
初始化分片。
调用ossClient.initiateMultipartUpload方法返回OSS创建的全局唯一的uploadId。
将文件进行分片,并上传分片。
调用ossClient.uploadPart方法上传分片数据。
- 对于同一个uploadId,分片号(partNumber)标识了该分片在整个文件内的相对位置。如果使用同一个分片号上传了新的数据,那么OSS上这个分片已有的数据将会被覆盖。
- OSS将收到的分片数据的MD5值放在ETag头内返回给用户。
- OSS计算上传数据的MD5值,并与SDK计算的MD5值比较,如果不一致则返回InvalidDigest错误码。
合并分片。
所有分片上传完成后,调用ossClient.completeMultipartUpload方法将所有分片合并成完整的文件。
初始化分片
以下代码用于初始化分片:
// Endpoint以华北三为例,其它Region请按实际情况填写
String endpoint = "oss.cn-north-3.inspurcloudoss.com";
String accessKey = "<yourAccessKey>";
String secretKey = "<yourSecretKey>";
String bucketName = "<yourBucketName>";
String key = "<yourObjectName>";
//创建OSSClient实例
OSSClientImpl ossClient = new OSSClientImpl(endpoint, accessKey, secretKey);
//初始化分片
InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(bucketName, key);
InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(initiateMultipartUploadRequest);
System.out.println("Initiating Multipart: " + initiateMultipartUploadResult);
上传分片
以下代码用于上传分片:
// Endpoint以华北三为例,其它Region请按实际情况填写
String endpoint = "oss.cn-north-3.inspurcloudoss.com";
String accessKey = "<yourAccessKey>";
String secretKey = "<yourSecretKey>";
String bucketName = "<yourBucketName>";
String key = "<yourObjectName>";
//创建OSSClient实例
OSSClientImpl ossClient = new OSSClientImpl(endpoint, accessKey, secretKey);
//上传碎片
//fileName需要是文件的物理路径
//objectUploadId表示文件的上传ID号,可以在初始化文件(ossClient.initiateMultipartUpload)的返回值得到
UploadPartRequest uploadPartRequest = new UploadPartRequest(bucketName, key, "<objectUploadId>", new File("<fileName>"));
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
System.out.println("Uploading part: " + uploadPartResult);
合并分片
以下代码用于合并分片:
// Endpoint以华北三为例,其它Region请按实际情况填写
String endpoint = "oss.cn-north-3.inspurcloudoss.com";
String accessKey = "<yourAccessKey>";
String secretKey = "<yourSecretKey>";
String bucketName = "<yourBucketName>";
String key = "<yourObjectName>";
//创建OSSClient实例
OSSClientImpl ossClient = new OSSClientImpl(endpoint, accessKey, secretKey);
//合并碎片
//第一个参数表示分片编号(partNumber),在分片的时候生成
//partETag表示分片的ETag号,可以在上传分片的返回值中得到
PartETag eTag = new PartETag(1, "<partETag>");
List<PartETag> eTags = new ArrayList<>();
eTags.add(eTag);
//objectUploadId表示文件的上传ID号,可以在初始化文件(ossClient.initiateMultipartUpload)的返回值得到
CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, key, "<objectUploadId>", eTags);
CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
System.out.println("Completing Multipart: " + completeMultipartUploadResult);
完整分片上传
以下代码用于分片上传:
// Endpoint以华北三为例,其它Region请按实际情况填写
String endpoint = "oss.cn-north-3.inspurcloudoss.com";
String accessKey = "<yourAccessKey>";
String secretKey = "<yourSecretKey>";
String bucketName = "<yourBucketName>";
String key = "<yourObjectName>";
//创建OSSClient实例
OSSClientImpl ossClient = new OSSClientImpl(endpoint, accessKey, secretKey);
//初始化文件,获取uploadId
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, key);
//初始化文件,必须设置文件上传后的访问权限
request.setAcl(CannedAccessControlList.PublicRead);
InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient.initiateMultipartUpload(request);
//以本地文件test.exe为上传文件,并获取文件大小
File file = new File("D:\\test.exe");
long fileLength = file.length();
//以每片大小为5M为例
long perPartSize = 5 * 1024 * 1024;
//获取分片数量
long partCount = fileLength / perPartSize;
//如果分片的最后一片小于每片的大小,需要加上最后一片
if (fileLength % perPartSize != 0) {
partCount++;
}
//如果文件大小为0需要设置分片数为1,否则会抛异常
if (fileLength == 0) {
partCount = 1;
}
//partETags用来记录每一个分片上传后的partEtag(用来标识分片),用来最后进行分片合并
List<PartETag> partETags = new ArrayList<>();
for (int i = 0; i < partCount; i++) {
long startPos = i * perPartSize;
//判断是都是最后一片,如果是最后一片,大小是小于等于每一片大小的,需要设置大小为最后一片的大小
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : perPartSize;
//跳过上一次已经上传的字节数,让上一次上传字节的后一个字节作为这一次上传的开始位置
InputStream inputStream = new FileInputStream(file);
inputStream.skip(startPos);
UploadPartRequest uploadPartRequest = new UploadPartRequest(bucketName, key, initiateMultipartUploadResult.getUploadId(), inputStream);
uploadPartRequest.setPartSize(curPartSize);
uploadPartRequest.setPartNumber( i + 1);
//上传分片
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
//保存分片的partEtag
partETags.add(new PartETag(uploadPartResult.getPartNumber(), uploadPartResult.geteTag()));
}
//进行文件的合并
CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, key,
initiateMultipartUploadResult.getUploadId(),partETags);
ossClient.completeMultipartUpload(completeMultipartUploadRequest);
中止分片上传
以下代码用于中止上传:
// Endpoint以华北三为例,其它Region请按实际情况填写
String endpoint = "oss.cn-north-3.inspurcloudoss.com";
String accessKey = "<yourAccessKey>";
String secretKey = "<yourSecretKey>";
String bucketName = "<yourBucketName>";
String key = "<yourObjectName>";
//创建OSSClient实例
OSSClientImpl ossClient = new OSSClientImpl(endpoint, accessKey, secretKey);
//中止分片上传
//objectUploadId表示文件的上传ID号,可以在初始化文件(ossClient.initiateMultipartUpload)的返回值得到
AbortMultipartUploadRequest abortIncompleteMultipartUpload = new AbortMultipartUploadRequest(bucketName, key, "<objectUploadId>");
ossClient.abortMultipartUpload(abortIncompleteMultipartUpload);
列举分片上传事件
调用ossClient.getMultipartUploadList(ListMultipartUploadsRequest listMultipartUploadsRequest)方法列举出指定存储桶下所有已经上传成功的分片,参数ListMultipartUploadsRequest 主要包含以下属性:
属性 | 描述 |
---|---|
String bucketName | 存储桶的名字 |
String keyMarker | 所有文件名称的字母序大于keyMarker参数值的分片上传事件。可以与uploadIdMarker参数一同使用来指定返回结果的起始位置。 |
String uploadIdMarker | 与keyMarker参数一同使用来指定返回结果的起始位置。 如果未设置keyMarker参数,则此参数无效。如果设置了keyMarker参数,则查询结果中包含:名称的字母序大于keyMarker参数值的所有文件;文件名称等于keyMarker参数值且uploadId比uploadIdMarker参数值大的所有分片上传事件。 |
String prefix | 限定返回的文件名称必须以指定的prefix作为前缀。注意使用prefix查询时,返回的文件名称中仍会包含prefix。 |
String delimiter | 用于对文件名称进行分组的一个字符。所有名称包含指定的前缀且第一次出现delimiter字符之间的文件作为一组元素。 |
Integer maxUploads | 限定此次返回分片上传事件的最大数目,默认值和最大值均为1000。 |
String encodingType | 限定文件的编码格式,在其他基础上进一步限制返回结果 |
列举全部分片上传事件
默认情况下,listMultipartUploads 只能一次列举1000个分片。当分片数量大于1000时,可以采用以下代码列举全部分片上传事件。
// Endpoint以华北三为例,其它Region请按实际情况填写
String endpoint = "oss.cn-north-3.inspurcloudoss.com";
String accessKey = "<yourAccessKey>";
String secretKey = "<yourSecretKey>";
String bucketName = "<yourBucketName>";
//创建OSSClient实例
OSSClientImpl ossClient = new OSSClientImpl(endpoint, accessKey, secretKey);
// 列举分片上传事件。默认列举1000个分片
ListMultipartUploadsRequest listMultipartUploadsRequest = new ListMultipartUploadsRequest(bucketName);
MultipartUploadListing multipartUploadListing;
do {
multipartUploadListing = ossClient.getMultipartUploadList(listMultipartUploadsRequest);
for (Upload upload : multipartUploadListing.getUploads()) {
// 获取Key
System.out.println(upload.getKey());
// 获取uploadId
System.out.println(upload.getUploadId());
// 获取分片上传存储类型
System.out.println(upload.getStorageClass());
// 获取分片上传的用户信息
System.out.println(upload.getOwner());
// 获取分片上传的初始化时间
System.out.println(upload.getInitiated());
}
//设置下一次开始的位置为已经获取1000个后的下一个文件名称
listMultipartUploadsRequest.setKeyMarker(multipartUploadListing.getNextKeyMarker());
//设置下一次开始的uploadId位置 listMultipartUploadsRequest.setUploadIdMarker(multipartUploadListing.getNextUploadIdMarker());
} while (multipartUploadListing.isTruncated());
分页列举全部上传事件
以下代码用于分页列举所有上传事件:
// Endpoint以华北三为例,其它Region请按实际情况填写
String endpoint = "oss.cn-north-3.inspurcloudoss.com";
String accessKey = "<yourAccessKey>";
String secretKey = "<yourSecretKey>";
String bucketName = "<yourBucketName>";
//创建OSSClient实例
OSSClientImpl ossClient = new OSSClientImpl(endpoint, accessKey, secretKey);
//设置每一页需要列举的分片上传事件数目
ListMultipartUploadsRequest listMultipartUploadsRequest = new ListMultipartUploadsRequest(bucketName);
listMultipartUploadsRequest.setMaxUploads(20);
MultipartUploadListing multipartUploadListing;
do {
multipartUploadListing = ossClient.getMultipartUploadList(listMultipartUploadsRequest);
for (Upload upload : multipartUploadListing.getUploads()) {
// 获取Key
System.out.println(upload.getKey());
// 获取uploadId
System.out.println(upload.getUploadId());
// 获取分片上传存储类型
System.out.println(upload.getStorageClass());
// 获取分片上传的用户信息
System.out.println(upload.getOwner());
// 获取分片上传的初始化时间
System.out.println(upload.getInitiated());
}
//设置下一次开始的位置为已经获取20个后的下一个文件名称
listMultipartUploadsRequest.setKeyMarker(multipartUploadListing.getNextKeyMarker());
//设置下一次开始的uploadId位置 listMultipartUploadsRequest.setUploadIdMarker(multipartUploadListing.getNextUploadIdMarker());
} while (multipartUploadListing.isTruncated());