Estoy tratando de cargar archivos grandes en un cubo s3 usando node.js aws-sdk .
la carga del método V2 upload integralmente los archivos en una carga de varias partes.
Quiero usar el nuevo V3 aws-sdk. ¿Cuál es la forma de cargar archivos grandes en la nueva versión? El método PutObjectCommand no parece estar funcionando.
He visto que hay métodos como CreateMultiPartUpload pero parece que no puedo encontrar un ejemplo de trabajo completo usándolos.
Gracias por adelantado.
A partir de 2021, sugeriría usar el paquetede almacenamiento lib , que abstrae muchos de los detalles de implementación.
Código de muestra:
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); }Fuente:https://github.com/aws/aws-sdk-js-v3/blob/main/lib/lib-storage/README.md
Esto es lo que se me ocurrió, cargar un búfer como una carga de varias partes, usando aws-sdk v3 para nodejs y TypeScript.
El manejo de errores todavía necesita algo de trabajo (es posible que desee abortar/reintentar en caso de error), pero debería ser un buen punto de partida... He probado esto con archivos XML de hasta 15 MB, y hasta ahora todo bien. ¡Sin embargo, no hay garantías! ;)
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 } }