I try to load a group of XML files from a ftp Server by using the ftp node module.
It worked not so I needed. No async/await is implemented. It's bad to integrate in good readable code.
Is there a better way?
my bad code is (it work, but this asynchron staff is confused!):
import Client from 'ftp';
import ReadableStream = NodeJS.ReadableStream;
const c = new Client();
function streamToString(stream: ReadableStream) {
// lets have a ReadableStream as a stream variable
const chunks = [];
for await (const chunk of stream) {
chunks.push(Buffer.from(chunk));
}
return Buffer.concat(chunks).toString("utf-8");
}
const getFile = async () => {
let fname: string = ""
c.on('ready', () => {
c.list(".", async (err, list) => {
if (err) throw err;
// console.dir(list);
for (const fileProp of list) {
console.log("fileProp: " , './' +fileProp.name)
fname = fileProp.name
if(fileProp.name.match(/.*\.xml/)){
c.get('./' + fileProp.name, (err, stream) => {
if (err) throw err;
console.log("fname: " + fname)
const result = streamToString(stream)
console.log("file content:\n" + result)
return
});
}
}
c.end();
});
});
c.on('error', () => {
console.log('handle error');
});
await c.connect({
host: "myserver.com",
user: "myuser",
password: "mypassword",
//debug: m => console.log(m)
})
}
The better way is to use the basic-ftp module. The ftp module is very old and has not implemented the async/await feature.
So with basic-ftp you can implement a clear straight forward solution - simple and good readable.
import * as streamBuffers from "stream-buffers"
import * as ftp from "basic-ftp"
import {FileInfo} from "basic-ftp";
const testFtp = async () => {
await baseFtpTest()
console.log("end testFtp")
}
const baseFtpTest = async () => {
const client = new ftp.Client()
client.ftp.verbose = true
try {
await client.access({
host: "myserver.com",
user: "myuser",
password: "mypassword",
//secure: true
})
console.log(await client.list())
let flist: FileInfo[] = await client.list()
for (const fileProp of flist) {
if(fileProp.name.match(/.*\.xml/)) {
console.log("fname: " + fileProp.name)
let sbuff: streamBuffers.WritableStreamBuffer = new streamBuffers.WritableStreamBuffer()
await client.downloadTo(sbuff, fileProp.name)
let content: string | false = sbuff.getContentsAsString()
console.log("content:", content)
}
}
}
catch(err) {
console.log(err)
}
client.close()
}
debugger
testFtp()