在NodeJS中,如何从S3下载文件

use*_*827 4 amazon-s3 node.js express aws-sdk

在 ExpressJS 中,我想下载之前上传到 Amazon S3 存储桶的文件。

这是我当前的路线:

const express = require('express');
const AWS = require('aws-sdk');
const mammoth = require('mammoth');
const fs = require('fs').promises
const path = require('path')
const router = express.Router();

router.put('/:id/download', async (req, res, next) => {
  console.log('hitting download route')

  var id = req.params.id;
  let upload = await Upload.query().findById( id ).eager('user');

  console.log("file to download is: ", upload.name)

  AWS.config.update({
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  });

  const s3 = new AWS.S3();


  // var fileStream = fs.createWriteStream('/tmp/file.docx');
  // var s3Stream = s3.getObject(params).createReadStream();

  const downloadFromS3 = async () => {
    const params = {
      Bucket: process.env.AWS_BUCKET, 
      Key: upload.file_url.split("com/").reverse()[0]
    };
    const { Body } = await s3.getObject(params).promise()
    await fs.writeFile(`${ __dirname }/download.docx`, Body)

    return Body
  }


  // mammoth.convertToHtml({ path: '/Users/dariusgoore/Downloads/1585930968750.docx' })
  //   .then(async function(result) {
  //     await Upload.query().findById( id )
  //       .patch({
  //          html: result.value,
  //          conversion_messages: result.messages
  //       })  
  //     res.json(result);
  //   })

    // .done();

  res.send(downloadFromS3)
});
Run Code Online (Sandbox Code Playgroud)

我没有收到任何错误,但未创建该文件,或者如果我手动创建该文件,它仍为空。

raz*_*zki 7

如果我理解正确的话,问题是您没有等待文件写入本地文件系统,而是通过 Express 在响应中返回它。

尝试一下这段代码。

const express = require('express')
const AWS = require('aws-sdk')
const mammoth = require('mammoth')

const fs = require('fs').promises
const path = require('path')

const router = express.Router()

const s3 = new AWS.S3()

AWS.config.update({
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
})

const downloadFromS3 = async (key, location) => {
    const params = {
        Bucket: process.env.AWS_BUCKET,
        Key: key,
    }

    const { Body } = await s3.getObject(params).promise()
    await fs.writeFile(location, Body)

    return true
}

router.put('/:id/download', async (req, res, next) => {
    console.log('hitting download route')

    const upload = await Upload.query()
        .findById(req.params.id)
        .eager('user')

    console.log('file to download is: ', upload.name)

    const key = upload.file_url.split('com/').reverse()[0]

    const location = `${__dirname}/${key}.docx`

    await downloadFromS3(key, location)

    res.send({ key, location })
})
Run Code Online (Sandbox Code Playgroud)