当前位置: 首页 > 知识库问答 >
问题:

使用node.js将aws sdk多部分上传到s3

苏墨竹
2023-03-14

我正在尝试使用node.jsaws-sdk将大文件上传到s3存储桶。

V2 方法上传以分段上传方式完整上传文件。

我想使用新的V3 aws-sdk。在新版本中上传大文件的方法是什么?方法PutObjectCommand似乎没有这样做。

我见过一些方法,例如CreateMultiPartUpload,但我似乎找不到使用它们的完整工作示例。

先谢谢你。

共有2个答案

姜宏放
2023-03-14

这是我想到的,使用aws-sdk v3为nodejs和TypeScript上传一个缓冲区作为多部分上传。

错误处理仍然需要一些工作(您可能希望在发生错误时中止/重试),但它应该是一个很好的起点...我已经用高达15MB的XML文件对此进行了测试,到目前为止还不错。但是,不能保证!;)

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
  }
}

云宜人
2023-03-14

从2021起,我建议使用lib存储包,它抽象了许多实现细节。

示例代码:

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 冰川的评估。由于大小,我无法在一个请求中执行此操作,因此我需要将其拆分为较小的部分并使用分段上传。 Boto3是否包含一个方法,该方法获取一个大文件,拆分并逐个上传它的部分?正如我所见Java客户端有这样的方法(取自AWS文档): 高级API提供了一种方法,您可以使用该方法上传任何大小的存档。根据您要上传的文件,该方法可以在单个操作中上传存档,也可以使用Amaz

  • 我正在尝试向S3发出上传请求,以便上传一个文件。在我目前掌握的最可靠的代码下面, 我总是从服务器收到400(错误请求)。我不确定我是否正确使用了多部分上传。 但是当我使用像POSTMAN这样的任何Rest客户端做同样的事情时,它工作得很好, 这将是有帮助的,如果有人可以抛出一些光在多部分上传放心。 我已经查看了以下链接, 放心文档 放心的示例 编辑1: 我试着将上面的邮递员请求转换成curl,并用

  • 我试图用python写的lambda (aws)完成多部分上传。下面是我正在使用的代码。大约有120个部件,总大小为30GB。下面的操作似乎没有在5分钟内完成,因此lambda关闭,上传似乎没有完成。S3提供异步多部分上传功能吗?我相信这将确保文件得到合并,不管lambda关闭。

  • 嗨,我有一个问题,当我可以尝试上载一个文件的属性和元数据到alFresco 5.2使用php 5.4.3,这是我的代码: $pam['body']是这样的: 这显示此错误: 但这个错误意味着一个或多个参数是错误的,但我不知道是哪个,因为服务器有大量的磁盘空间。 有什么帮助吗?有人使用ApiRest Alfresco 5.2和PHP吗?

  • 下面是我的视图表单: 下面是视图控制器: 展厅服务: “用严”;

  • 在Android中使用OKHTTP以多部分方式上传单个大文件(更具体地说,上传到s3)时,我有什么选择?