标准接口
PutObject只能上传小于5GB的对象,如果需要上传超过5GB的对象,您必须使用分片上传模式。
使用createMultipartUpload接口创建分片上传任务,该接口会返回一个UploadId,客户端使用这个UploadId来上传分片。
startUpload: function () {
console.log("upload")
let key = "ExampleObject.txt"
let localFile = "E:/movie/3.flv"
let size = 0
try {
var stats = fs.statSync(localFile);
if(stats.size <= this.partSize) {
console.log('file size %d too small', stats.size)
return
}
size = stats.size
this.numPartsLeft = Math.ceil(size / this.partSize);
} catch(err) {
console.log('statSync err %s', err)
}
let createParams = {
Bucket: this.bucket,
Key: key,
};
this.s3Client.createMultipartUpload(createParams, (err, createRes) => {
if (err) {
console.log("createMultipartUpload error", err);
return;
}
console.log("createMultipartUpload success", createRes)
this.createRes = createRes
let partNum = 0
let f = fs.createReadStream(localFile)
f.on('readable', () => {
while ((buf=f.read(this.partSize)) != null) {
partNum++
this.uploadPart(buf, partNum)
}
});
});
},
使用uploadPart接口可以进行分片上传
uploadPart: function(buf, partNum) {
console.log('uploadPart #%d, length: %d', partNum, buf.length)
let partParams = {
Body: buf,
PartNumber: String(partNum),
Bucket: this.createRes.Bucket,
Key: this.createRes.Key,
UploadId: this.createRes.UploadId
}
this.s3Client.uploadPart(partParams, (err, data) => {
if (err){
console.log('uploadPart error:', err);
this.abortMultipartUpload();
return;
}
this.multipartMap.Parts[partParams.PartNumber - 1] = {
ETag: data.ETag,
PartNumber: Number(partParams.PartNumber)
};
console.log("uploadPart completed ", partParams.PartNumber);
--this.numPartsLeft
if (this.numPartsLeft > 0)
return;
this.completeMultipartUpload();
});
},
使用completeMultipartUpload完成分片上传任务
completeMultipartUpload: function() {
console.log("completeMultipartUpload");
var params = {
Bucket: this.createRes.Bucket,
Key: this.createRes.Key,
UploadId: this.createRes.UploadId,
MultipartUpload: this.multipartMap,
};
this.s3Client.completeMultipartUpload(params, function(err, data) {
if (err) {
console.log('completeMultipartUpload err, ', err);
this.abortMultipartUpload();
} else {
console.log('completeMultipartUpload success');
}
});
},
使用abortMultipartUpload取消分片上传任务
abortMultipartUpload: function() {
console.log("abortMultipartUpload");
var params = {
Bucket: this.createRes.Bucket,
Key: this.createRes.Key,
UploadId: this.createRes.UploadId
};
this.s3Client.abortMultipartUpload(params, function(err, data) {
if (err) {
console.log('abortMultipartUpload err, ', err);
} else {
console.log('abortMultipartUpload success');
}
});
},
使用listParts可以根据UploadId列举已完成上传的分片。可以使用此接口实现断点续传,在客户端保存UploadId和对应的本地文件路径,重新上传的时候先通过listParts获取到已上传的分片,避免重复上传这些分片,从而实现断点续传
listParts: function(key, uploadId) {
console.log("listParts");
var params = {
Bucket: this.bucket,
Key: key,
UploadId: uploadId
};
this.s3Client.listParts(params, function(err, data) {
if (err) {
console.log('listParts err, ', err);
} else {
console.log('listParts success, ', data);
}
});
},
使用listMultipartUploads可以列举所有未完成上传的分片上传任务Id
listMultipartUploads: function() {
console.log("listMultipartUploads");
var params = {
Bucket: this.bucket,
};
this.s3Client.listMultipartUploads(params, function(err, data) {
if (err) {
console.log('listMultipartUploads err, ', err);
} else {
console.log('listMultipartUploads success, ', data);
}
});
},