在CreateMultipartUploadCommand返回的Promise中添加对ETag的解析,并在调用CompleteMultipartUploadCommand时将其作为参数传递。
示例代码如下:
const { S3Client, CreateMultipartUploadCommand, UploadPartCommand, CompleteMultipartUploadCommand } = require('@aws-sdk/client-s3');
const { Readable } = require('stream');
const s3 = new S3Client({ region: 'us-east-1' });
async function uploadFile(bucketName, key, filePath) {
const fileStream = fs.createReadStream(filePath);
// 创建Initiate Multipart Upload请求
const initResult = await s3.send(new CreateMultipartUploadCommand({ Bucket: bucketName, Key: key }));
const parts = [];
// 分块上传
for await (const part of uploadParts(initResult.UploadId, fileStream)) {
parts.push(part);
}
// 完成Multipart Upload请求
const completeResult = await s3.send(new CompleteMultipartUploadCommand({
Bucket: bucketName,
Key: key,
UploadId: initResult.UploadId,
MultipartUpload: { Parts: parts }
}));
return completeResult.Location;
}
async function* uploadParts(uploadId, fileStream) {
let partNo = 0;
while (true) {
const chunk = await getFileChunk(fileStream);
if (!chunk || chunk.length === 0) {
break;
}
const uploadResult = await s3.send(new UploadPartCommand({
Bucket: bucketName,
Key: key,
UploadId: uploadId,
Body: chunk,
PartNumber: ++partNo
}));
console.log(`Uploaded part ${partNo}: ${uploadResult.ETag}`);
yield { ETag: uploadResult.ETag, PartNumber: partNo };
}
}
function getFileChunk(fileStream) {
return new Promise(resolve => {
const readable = new Readable({
read() {
const chunk = fileStream.read(1024 * 1024);
if (chunk) {
this.push(chunk);
} else {
this.push(null);
}
resolve(chunk);
}
});
readable.on('error', () => resolve(null));
});
}