- 产品文档
- > 存储与 CDN
- > 对象存储
- > AWS S3 兼容
- > AWS S3 SDK
- > S3 Java SDK手册
- > 文件上传
文件上传
在NOS中,用户的每个文件都是一个Object(对象)。
NOS提供两种文件上传方式:普通上传(PutObject),上传小于或等于100M的文件;分块上传(MultiUpload),大文件可以采用该方式上传。
AWS Java SDK提供了丰富的文件上传接口与功能,主要有:
- 直接内容上传
- 本地文件普通上传
- 支持上传文件时设置文件元数据信息
- 流式上传
- 分块上传
下述除了分块上传不能直接使用加密client替换外,其他的都是可以直接替换使用
直接内容上传
对于一些简单的字符串内容,可以使用putObject进行上传。代码示例如下:
//要上传文件的路径
String content = "Object content";
try {
s3Client.putObject("your-bucketname","your-objectname",content);
}catch (Exception e){
System.out.println(e.getMessage());
}
本地文件普通上传
对于小对象可以使用putObject接口进行上传,putObject上传支持的最大文件大小为100M,如果上传大于100M的文件需要使用分块上传。本地文件普通上传的示例代码如下:
//要上传文件的路径
String filePath = "your-local-file-path";
try {
s3Client.putObject("your-bucketname","your-objectname", new File(filePath));
}catch (Exception e){
System.out.println(e.getMessage());
}
上传文件时设置文件元数据信息
您可以在上传文件时设置文件元数据信息。可以设置的元数据主要有文件的Content-Type和用户自定义元数据信息。 这里以普通上传为例:
String filePath = "your-local-file-path";
ObjectMetadata objectMetadata = new ObjectMetadata();
//设置Content-Type
objectMetadata.setContentType("application/xml");
//设置标准http消息头(元数据)
objectMetadata.setHeader("Cache-Control", "no-cache");
//设置用户自定义元数据信息
Map<String, String> userMeta = new HashMap<String, String>();
userMeta.put("ud", "test");
objectMetadata.setUserMetadata(userMeta);
PutObjectRequest putObjectRequest = new PutObjectRequest("your-bucketname","your-objectname", new File(filePath));
putObjectRequest.setMetadata(objectMetadata);
s3Client.putObject(putObjectRequest);
流式上传
try {
ObjectMetadata objectMetadata = new ObjectMetadata();
//设置流的长度,您还可以设置其他文件元数据信息
objectMetadata.setContentLength(streamLength);
s3Client.putObject("your-bucketname","your-objectname", inputStream, objectMetadata)
}catch (Exception e){
System.out.println(e.getMessage());
}
分块上传
对于大于100M的对象必须进行分块上传,分块上传的最小单位单位为16K,最后一块可以小于16K,最大单位为100M,较大文件使用分块上传失败的代价比较小,只需要重新上传失败的分块即可; 在文件已经全部存在情况下可以进行分块并发上传。
初始化分块上传
//初始化一个分块上传,获取分块上传ID,桶名 + 对像名 + 分块上传ID 唯一确定一个分块上传
is = new FileInputStream("youFilePath");
InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest("your-bucketname", "your-objectname");
//您还可以在初始化分块上传时,设置文件的Content-Type
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType("application/xml");
initRequest.setObjectMetadata(objectMetadata);
InitiateMultipartUploadResult initResult = s3Client.initiateMultipartUpload(initRequest);
String uploadId = initResult.getUploadId();
进行分块上传
下面是顺序上传所有分块的示例,您也可以进行并发上传。
long filePosition = 0;
for (int i = 1; filePosition < contentLength; i++) {
// Last part can be less than 5 MB. Adjust part size.
partSize = Math.min(partSize, (contentLength - filePosition));
// Create request to upload a part.
UploadPartRequest uploadRequest = new UploadPartRequest()
.withBucketName(bucketName).withKey(key)
.withUploadId(uploadId).withPartNumber(i)
.withFileOffset(filePosition)
.withFile(file) //要上传的文件对象
.withPartSize(partSize);
//如果是加密的,需要加入这步
if (filePosition + partSize == contentLength){
uploadRequest.setLastPart(true);
}
// Upload part and add response to our list.
partETags.add(encryptionClient.uploadPart(uploadRequest).getPartETag());
ListPartsRequest listPartsRequest = new ListPartsRequest(bucketName, key, initResponse.getUploadId());
encryptionClient.listParts(listPartsRequest);
filePosition += partSize;
}
列出所有分块
//这里可以检查分块是否全部上传,分块MD5是否与本地计算相符,如果不符或者缺少可以重新上传
List<PartETag> partETags = new ArrayList<PartETag>();
int nextMarker = 0;
while (true) {
ListPartsRequest listPartsRequest = new ListPartsRequest("your-bucketname",
"your-objectname", uploadId);
listPartsRequest.setPartNumberMarker(nextMarker);
PartListing partList = s3Client.listParts(listPartsRequest);
for (PartSummary ps : partList.getParts()) {
nextMarker++;
partETags.add(new PartETag(ps.getPartNumber(), ps.getETag()));
}
if (!partList.isTruncated()) {
break;
}
}
完成分块上传
CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest(
"your-bucketname","your-objectname", uploadId, partETags);
CompleteMultipartUploadResult completeResult = s3Client.completeMultipartUpload(completeRequest);
取消分块上传
s3Client.abortMultipartUpload(new AbortMultipartUploadRequest(
bucketName, key, initResponse.getUploadId()));