我一直在努力使用各种FTP节点模块来尝试在AWS Lambda中工作。最好的和最流行的似乎是“Basic-FTP”,它也支持async / await。但是,当FTP功能下添加任何代码时,我无法下载文件。
我不想在FTP异步函数中添加fs函数,因为我需要在添加下面的任何代码时解决导致中断的原因,并且还有其他代码来添加和处理下载的文件及其内容后来:
FTP成功 - 当只使用async函数时,它下面没有fs代码
FTP FAILURE - 添加fs readdir / readFile函数或下面的任何其他代码
错误Error: ENOENT: no such file or directory, open '/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: '[email protected]',
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日志:
我的文件里面只包含一个'hello'。你可以在日志上看到它。
请记住,在Lambda函数中,将任何内容下载到/ tmp时,您有512MB的限制。您可以在docs中看到限制