Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save file from S3 using aws-sdk v3

With the new aws-sdk v3, specifically @aws-sdk/client-s3, it's not clear to me how to store files to disk from S3.
Having the following code

const { Body } = await s3.send(new GetObjectCommand({
  Bucket: 'myBucket',
  Key: 'myKey',
}))

The Body can be of type Readable | ReadableStream | Blob.
I'd like to store this into a file on disk. Since the return types are completely different, is there an easy way to e.g. get a Buffer or Stream.Readable from aws-sdk?

In aws-sdk v2 it was easy with .createReadStream() function which seems to no longer exist.

like image 996
mike Avatar asked Mar 18 '21 10:03

mike


People also ask

Can S3 be used to store files?

Amazon S3 is a service that enables you to store your data (referred to as objects) at massive scale. In this guide, you will create an Amazon S3 bucket (a container for data stored in S3), upload a file, retrieve the file, and delete the file.

How do I save a file in S3 bucket?

To upload folders and files to an S3 bucket Sign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ . In the Buckets list, choose the name of the bucket that you want to upload your folders or files to. Choose Upload.

How do I get files from AWS S3?

In the Amazon S3 console, choose your S3 bucket, choose the file that you want to open or download, choose Actions, and then choose Open or Download. If you are downloading an object, specify where you want to save it. The procedure for saving the object depends on the browser and operating system that you are using.

What is AWS S3 SDK?

Amazon Simple Storage Service (Amazon S3) is a web service that provides highly scalable cloud storage. Amazon S3 provides easy to use object storage, with a simple web service interface to store and retrieve any amount of data from anywhere on the web. The JavaScript API for Amazon S3 is exposed through the AWS.

How do I use the AWS SDKs for S3?

You can use the AWS SDKs when developing applications with Amazon S3. The AWS SDKs simplify your programming tasks by wrapping the underlying REST API.

How to install AWS-SDK in AWS?

To install aws-sdk, you can simply use npm package manager to do below. And here is the simple code to generate the download URL. First, you need to create S3 bucket object. And then, use getSignedUrlPromise () to receive the generated download url.

What AWS SDKs are available for Visual Studio?

In addition to the AWS SDKs, AWS Explorers are available for Visual Studio and Eclipse for Java IDE. In this case, the SDKs and the explorers are available bundled together as AWS Toolkits. You can also use the AWS Command Line Interface (AWS CLI) to manage Amazon S3 buckets and objects.

How do I manage Amazon S3 buckets and objects?

You can also use the AWS Command Line Interface (AWS CLI) to manage Amazon S3 buckets and objects. The AWS Toolkit for Eclipse includes both the AWS SDK for Java and AWS Explorer for Eclipse.


Video Answer


2 Answers

It appears ReadableStream | Blob is available only in browser. Node.js always gets Readable which is what I need.

The solution is pretty straightforward afterwards with fs.createWriteStream and piping the Readable such as

await new Promise((resolve, reject) => {
  Body.pipe(fs.createWriteStream(filePath))
    .on('error', err => reject(err))
    .on('close', () => resolve())
})

For reference, here's an issue where improvement to documentation is discussed https://github.com/aws/aws-sdk-js-v3/issues/1877

like image 50
mike Avatar answered Nov 15 '22 08:11

mike


GetObjectCommand returns readable stream, we use fs module to create writeStream and pass the returned readableStream from GetObjectCommand to writeStream to save the file

const fs = require('fs');
const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');

const s3Client = new S3Client({
  region: 'your_region',
  credentials: { accessKeyId: 'your_accessKeyId', secretAccessKey: 'your_secretAccessKey' },
});

const bucketParams = {
  Bucket: 'your_bucket',
  Key: 'your_key.jpg',
};

const run = async () => {
  try {
    const data = await s3Client.send(new GetObjectCommand(bucketParams));
    const inputStream = data.Body;
    const downloadPath = 'example.png';
    const outputStream = fs.createWriteStream(downloadPath);
    inputStream.pipe(outputStream);
    outputStream.on('finish', () => {
      console.log(`downloaded the file successfully`);
    });
  } catch (err) {
    console.log('Error', err);
  }
};
like image 34
SRINIVASA YADAV TALAPANTI Avatar answered Nov 15 '22 07:11

SRINIVASA YADAV TALAPANTI