I am trying to download all files located within a specific folder on a FTP site. The folder is called “IN” (as shown in example code) and contains a number of .csv files.
the requirement are this:
- donwload to local folder all the csv present on the IN folder
- move them from IN folder on the FTP to ARCHIVE folder on the ftp folder
- Merge all the csv file to a new csv with all the content of the csv imported
i’m stuck to the secondo point. I use promise-ftp to do this process and here my code:
const fs = require("fs"); const Client = require("promise-ftp"); const sftp = new Client(); sftp .connect({ host: "xxxxx", port: 21, user: "xxxx", password: "xxxxx", }) .then(() => { console.log("connected"); // will return an array of objects with information about all files in the remote folder return sftp.list("/htdocs/IN"); }) .then(async (data) => { // data is the array of objects len = data.length; // x is one element of the array await data.forEach((x) => { let remoteFilePath = "/htdocs/IN/" + x.name; if (x.type === "-") { console.log(x.name); sftp .get(remoteFilePath) .then((stream) => { console.log("---------"); console.log(x.name); return new Promise(function (resolve, reject) { stream.once("close", resolve); stream.once("error", reject); stream.pipe(fs.createWriteStream("IN/" + x.name)); }); }) .then(() =>{ sftp .rename("/htdocs/IN/" + x.name, "/htdocs/OUT/" + x.name) .then(function () { console.log("rinominato"); }) console.log("qui cancello: " + x.name); }); } }); }).then(() => { sftp.end(); }) .catch((err) => { console.log(err, "catch error"); });
Now this script download all the file on my local storage but when i tried to rename it to another folder i receive this error:
Unhandled rejection FtpConnectionError: can't perform 'rename' command when connection status is: disconnecting
i think that i’m make some mistake on where put the sftp.close function but i’m new on node.js.
Anyone could help me to understand better where i’m wrong?
Added new version of the code with more async and await but still not working:
const fs = require("fs"); const Client = require("promise-ftp"); const ftp = new Client(); const downloadAndStoreFile = async () => { await ftp.connect({ host: "xxxx", port: 21, user: "xxx", password: "xxx", }); console.log ('connected'); let data = await ftp.list('/htdocs/IN'); data = data.filter(function (file) { return file.type === "-" ? file : null; }); console.log(data); data.forEach((file)=>{ if (file.type === '-'){ //console.log(file.name); const operation = async () => { console.log(file.name); const stream = await ftp.get("/htdocs/IN/" + file.name); const streamResult = await stream.pipe(fs.createWriteStream("IN/" + file.name)); const renameResult = await ftp.rename("/htdocs/IN/" + file.name, "/htdocs/OUT/" + file.name); }; operation(); } }); await ftp.end(); }; downloadAndStoreFile();
thank you
Advertisement
Answer
Please try the await way to do stuff like this:
const fs = require("fs"); const Client = require("promise-ftp"); const sftp = new Client(); sftp .connect({ host: "XXXX", port: 21, user: "XXX", password: "XXX", }) .then(() => { console.log("connected"); // will return an array of objects with information about all files in the remote folder return sftp.list("/htdocs/IN"); }) .then(async(data) => { // data is the array of objects len = data.length; for (let i = 0; i < len; i++) { let x = data[i]; // x is one element of the array let remoteFilePath = "/htdocs/IN/" + x.name; if (x.type === "-") { console.log(x.name); let stream = sftp.get(remoteFilePath); console.log("---------"); console.log(x.name); await stream.pipe(fs.createWriteStream("IN/" + x.name)); await sftp.rename("/htdocs/IN/" + x.name, "/htdocs/OUT/" + x.name) console.log("rinominato"); console.log("qui cancello: " + x.name); } } }).then(() => { sftp.end(); }) .catch((err) => { console.log(err, "catch error"); });