javascript - AWS Lambda 中的 FTP - 下载文件时出现问题(异步/等待)

标签 javascript node.js amazon-web-services ftp aws-lambda

我一直在努力使用各种 FTP Node 模块来尝试让任何东西在 AWS Lambda 中工作。最好和最受欢迎的似乎是也支持异步/等待的“Basic-FTP”。但是当在 FTP 功能下添加任何代码时,我就是无法让它下载文件。

我不想在 FTP 异步函数中添加 fs 函数,因为我需要解决添加以下任何代码时导致中断的原因,而且我还有其他代码要添加并使用下载的文件稍后是内容:

FTP SUCCESS - 当异步函数仅在其下方没有 fs 代码的情况下使用时

FTP 失败 - 添加 fs readdir/readFile 函数或下面的任何其他代码

错误 错误:ENOENT:没有这样的文件或目录,打开“/tmp/document.txt”

https://github.com/patrickjuchli/basic-ftp

const ftp = require("basic-ftp");
const fs = require("fs");
var FileNameWithExtension = "document.txt";
var ftpTXT;

exports.handler = async (event, context, callback) => {

    example();

    async function example() {
        const client = new ftp.Client();
        //client.ftp.verbose = true;
        try {
            await client.access({
                host: host,
                user: user,
                password: password,
                //secure: true
            });
            console.log(await client.list());
            await client.download(fs.createWriteStream('/tmp/' + FileNameWithExtension), FileNameWithExtension);
        }
        catch (err) {
            console.log(err);
        }
        client.close();
    }

    // Read the content from the /tmp/ directory to check FTP was succesful
    fs.readdir("/tmp/", function (err, data) {
        if (err) {
            return console.error("There was an error listing the /tmp/ contents.");
        }
        console.log('Contents of AWS Lambda /tmp/ directory: ', data);
    });

    // Read TXT file and convert into string format
    fs.readFile('/tmp/' + FileNameWithExtension, 'utf8', function (err, data) {
        if (err) throw err;
        ftpTXT = data;
        console.log(ftpTXT);
    });

    // Do other Node.js coding with the downloaded txt file and it's contents
};

最佳答案

问题是您在处理程序中创建异步函数时迷路了。由于 example() 是异步的,它返回一个 Promise。但是您不会 await 它,所以它的编码方式有点像一劳永逸。此外,您的 Lambda 会在您的回调被触发之前终止,因此即使下载它您也看不到它。

我建议您将回调包装在 Promises 中,这样您就可以轻松地从处理函数中await

我已经设法让它工作了:我已经使用 https://dlptest.com/ftp-test/ 进行测试,所以相应地改变它。此外,看到我自己上传了文件。所以如果你想复制这个例子,只需在你的项目的根目录下创建一个 readme.txt 并上传它。如果您的 FTP 服务器上已有此 readme.txt 文件,只需删除它上传文件的行。

这是一个工作示例:

const ftp = require("basic-ftp");
const fs = require("fs");
const FileNameWithExtension = "readme.txt";

module.exports.hello = async (event) => {

  const client = new ftp.Client();
  try {
    await client.access({
      host: 'ftp.dlptest.com',
      user: 'dlpuser@dlptest.com',
      password: 'puTeT3Yei1IJ4UYT7q0r'
    });
    console.log(await client.list());
    await client.upload(fs.createReadStream(FileNameWithExtension), FileNameWithExtension)
    await client.download(fs.createWriteStream('/tmp/' + FileNameWithExtension), FileNameWithExtension);
  }
  catch (err) {
    console.log('logging err')
    console.log(err);
  }
  client.close();

  console.log(await readdir('/tmp/'))

  console.log(await readfile('/tmp/', FileNameWithExtension))

  return {
    statusCode: 200,
    body: JSON.stringify({message: 'File downloaded successfully'})
  }

};

const readdir = dir => {
  return new Promise((res, rej) => {
    fs.readdir(dir, function (err, data) {
      if (err) {
        return rej(err);
      }
      return res(data)
    });
  })
}

const readfile = (dir, filename) => {
  return new Promise((res, rej) => {
    fs.readFile(dir + filename, 'utf8', function (err, data) {
      if (err) {
        return rej(err);
      }
      return res(data)
    })
  })
}

这是 Lambda 函数的输出:

enter image description here

这里是完整的 CloudWatch 日志:

enter image description here

我的文件中只包含一个“你好”。您可以在日志中看到它。

请记住,在 Lambda 函数中,将任何内容下载到/tmp 时有 512MB 的限制。您可以在 docs 中看到限制

关于javascript - AWS Lambda 中的 FTP - 下载文件时出现问题(异步/等待),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54958602/

相关文章:

javascript - 有没有更好/优雅的方法将 JavaScript 拆分值分配给变量?

javascript - 为什么 io.emit() 在 process.on() 中不起作用?

node.js - 在 Express 中将变量传递到路由模板的最简单方法?

amazon-web-services - AWS : how to import a SSL certificate in PFX format into AWS?

amazon-web-services - Neo4j 无法在 AWS 实例中启动

amazon-web-services - CloudFront 和 API 网关缺少身份验证 token 错误

javascript - 观察来自几个 jQuery UI 对话框的事件

javascript - 如何将WebRTC捕获的照片发布到服务器

javascript - Node 和 Chrome (V8) block 范围内的 const

node.js - 哪些错误将由express error 处理,哪些由uncaughtException 错误处理程序处理?