我一直在努力使用各种 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 函数的输出:
这里是完整的 CloudWatch 日志:
我的文件中只包含一个“你好”。您可以在日志中看到它。
请记住,在 Lambda 函数中,将任何内容下载到/tmp 时有 512MB 的限制。您可以在 docs 中看到限制
关于javascript - AWS Lambda 中的 FTP - 下载文件时出现问题(异步/等待),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54958602/