Multipart Upload/Download

MultipartUpload

หลังการทำงานเบื้องต้น

  • CreateMultipartUploadCommand -> ใช้สำหรับการ initiates การทำ multipart upload โดยข้อมูลที่ได้กลับมาจะเป็น upload ID ซึ่งจะถูกนำไปใช้สำหรับการ upload แต่ละ part ของ file

  • UploadPartCommand -> ใช้สำหรับการ upload file แต่ละ part

  • CompleteMultipartUploadCommand -> หลังจากทำการ upload ทุก part เรียบร้อยแล้ว จะเรียกใช้งาน Command นี้เพื่อทำการรวม file ที่ได้ upload ไป เป็นการเสร็จสิ้นการทำงาน

  • AbortMultipartUploadCommand -> หากการ upload ล้มเหลว command นี้จะถูกเรียกใช้งานเพื่อทำการลบข้อมูลที่ล้มเหลวออกไป

import {
    CreateMultipartUploadCommand,
    UploadPartCommand,
    CompleteMultipartUploadCommand,
    AbortMultipartUploadCommand,
    S3Client,
} from "@aws-sdk/client-s3";
import * as fs from 'fs';

export const main = async () => {

    const s3Client = new S3Client({
        region: ncs_region,
        endpoint: ncs_endpoint,
        credentials: ncs_credentials
    });

    const key = "video.mov";
    const file_path = 'video.mov';
    let uploadId;

    try {
        const multipartUpload = await s3Client.send(
            new CreateMultipartUploadCommand({
                Bucket: ncs_bucket,
                Key: key,
            }),
        );

        uploadId = multipartUpload.UploadId;


        const uploadPromises = [];
        // Multipart uploads require a minimum size of 5 MB per part.
        const partSize = 1024 * 1024 * 15;
        const stats = fs.statSync(file_path);
        const file_size = stats.size;
        const total_part = Math.ceil(file_size/partSize);
        let buffer = fs.readFileSync(file_path);

        // Upload each part.
        for (let i = 0; i < total_part; i++) {
            const start = i * partSize;
            const end = start + partSize;
            uploadPromises.push(
              s3Client
                .send(
                  new UploadPartCommand({
                    Bucket: ncs_bucket,
                    Key: key,
                    UploadId: uploadId,
                    Body: buffer.subarray(start, end),
                    PartNumber: i + 1,
                  }),
                )
                .then((d) => {
                  console.log("Part", i + 1, "uploaded");
                  return d;
                }),
            );
          }
      
          const uploadResults = await Promise.all(uploadPromises);
      
          return await s3Client.send(
            new CompleteMultipartUploadCommand({
              Bucket: ncs_bucket,
              Key: key,
              UploadId: uploadId,
              MultipartUpload: {
                Parts: uploadResults.map(({ ETag }, i) => ({
                  ETag,
                  PartNumber: i + 1,
                })),
              },
            }),
          );

    } catch (err) {
        console.error(err);

        if (uploadId) {
            const abortCommand = new AbortMultipartUploadCommand({
                Bucket: ncs_bucket,
                Key: key,
                UploadId: uploadId,
            });

            await s3Client.send(abortCommand);
        }
    }
};

main();

Last updated

#281: Doc Access S3 buckets with AWS S3 Client SDK

Change request updated