簡體   English   中英

aws sdk 使用 node.js 分段上傳到 s3

[英]aws sdk Multipart Upload to s3 with node.js

我正在嘗試使用 node.js aws-sdk將大文件上傳到 s3 存儲桶。

V2方式upload整體上傳文件在一個multipart upload

我想使用新的 V3 aws-sdk。 新版本上傳大文件的方式是什么? PutObjectCommand方法似乎沒有這樣做。

我已經看到有諸如CreateMultiPartUpload之類的方法,但我似乎找不到使用它們的完整工作示例。

提前致謝。

截至 2021 年,我建議使用lib-storage package,它抽象了很多實現細節。

示例代碼:

import { Upload } from "@aws-sdk/lib-storage";
import { S3Client, S3 } from "@aws-sdk/client-s3";

const target = { Bucket, Key, Body };
try {
  const parallelUploads3 = new Upload({
    client: new S3({}) || new S3Client({}),
    tags: [...], // optional tags
    queueSize: 4, // optional concurrency configuration
    partSize: 5MB, // optional size of each part
    leavePartsOnError: false, // optional manually handle dropped parts
    params: target,
  });

  parallelUploads3.on("httpUploadProgress", (progress) => {
    console.log(progress);
  });

  await parallelUploads3.done();
} catch (e) {
  console.log(e);
}

來源: https://github.com/aws/aws-sdk-js-v3/blob/main/lib/lib-storage/README.md

這是我想到的,使用 aws-sdk v3 for nodejs 和 TypeScript 將緩沖區上傳為分段上傳。

錯誤處理仍然需要做一些工作(如果出現錯誤,您可能想中止/重試),但這應該是一個很好的起點……我已經用 XML 個最大 15MB 的文件對此進行了測試,到目前為止一切順利。 但是,沒有任何保證; ;)

import {
  CompleteMultipartUploadCommand,
  CompleteMultipartUploadCommandInput,
  CreateMultipartUploadCommand,
  CreateMultipartUploadCommandInput,
  S3Client,
  UploadPartCommand,
  UploadPartCommandInput
} from '@aws-sdk/client-s3'

const client = new S3Client({ region: 'us-west-2' })

export const uploadMultiPartObject = async (file: Buffer, createParams: CreateMultipartUploadCommandInput): Promise<void> => {
  try {
    const createUploadResponse = await client.send(
      new CreateMultipartUploadCommand(createParams)
    )
    const { Bucket, Key } = createParams
    const { UploadId } = createUploadResponse
    console.log('Upload initiated. Upload ID: ', UploadId)

    // 5MB is the minimum part size
    // Last part can be any size (no min.)
    // Single part is treated as last part (no min.)
    const partSize = (1024 * 1024) * 5 // 5MB
    const fileSize = file.length
    const numParts = Math.ceil(fileSize / partSize)

    const uploadedParts = []
    let remainingBytes = fileSize

    for (let i = 1; i <= numParts; i ++) {
      let startOfPart = fileSize - remainingBytes
      let endOfPart = Math.min(partSize, startOfPart + remainingBytes)

      if (i > 1) {
        endOfPart = startOfPart + Math.min(partSize, remainingBytes)
        startOfPart += 1
      }

      const uploadParams: UploadPartCommandInput = {
        // add 1 to endOfPart due to slice end being non-inclusive
        Body: file.slice(startOfPart, endOfPart + 1),
        Bucket,
        Key,
        UploadId,
        PartNumber: i
      }
      const uploadPartResponse = await client.send(new UploadPartCommand(uploadParams))
      console.log(`Part #${i} uploaded. ETag: `, uploadPartResponse.ETag)

      remainingBytes -= Math.min(partSize, remainingBytes)

      // For each part upload, you must record the part number and the ETag value.
      // You must include these values in the subsequent request to complete the multipart upload.
      // https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html
      uploadedParts.push({ PartNumber: i, ETag: uploadPartResponse.ETag })
    }

    const completeParams: CompleteMultipartUploadCommandInput = {
      Bucket,
      Key,
      UploadId,
      MultipartUpload: {
        Parts: uploadedParts
      }
    }
    console.log('Completing upload...')
    const completeData = await client.send(new CompleteMultipartUploadCommand(completeParams))
    console.log('Upload complete: ', completeData.Key, '\n---')
  } catch(e) {
    throw e
  }
}

我正在嘗試使用 node.js aws-sdk將大文件上傳到 s3 存儲桶。

V2方法upload是在分段上傳中整體上傳文件。

我想使用新的 V3 aws-sdk。 新版本上傳大文件的方法是什么? PutObjectCommand方法似乎沒有這樣做。

我已經看到有諸如CreateMultiPartUpload之類的方法,但我似乎找不到使用它們的完整工作示例。

提前致謝。

這是 AWS SDK v3 的完整工作代碼

import { Upload } from "@aws-sdk/lib-storage";
import { S3Client, S3 } from "@aws-sdk/client-s3";
import { createReadStream } from 'fs';

const inputStream = createReadStream('clamav_db.zip');
const Bucket = process.env.DB_BUCKET
const Key = process.env.FILE_NAME
const Body = inputStream

const target = { Bucket, Key, Body};
try {
  const parallelUploads3 = new Upload({
    client: new S3Client({
      region: process.env.AWS_REGION,
      credentials: { accessKeyId: process.env.AWS_ACCESS_KEY, secretAccessKey: process.env.AWS_SECRET_KEY }
    }),
    queueSize: 4, // optional concurrency configuration
    partSize: 5242880, // optional size of each part
    leavePartsOnError: false, // optional manually handle dropped parts
    params: target,
  });

  parallelUploads3.on("httpUploadProgress", (progress) => {
    console.log(progress);
  });

  await parallelUploads3.done();
} catch (e) {
  console.log(e);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM