如何在Typescript中从FTP服务器获取一组XML文件?

huangapple go评论73阅读模式
英文:

How can I get a group of XML files from a ftp server in Typescript?

问题

我尝试使用ftp节点模块从ftp服务器加载一组XML文件。

它的工作方式并不如我所期望的那样。没有实现异步/等待。很难集成到易读的代码中。

是否有更好的方法?

我的糟糕代码是(它可以工作,但这种异步处理让人感到困惑):

import Client from 'ftp';
import ReadableStream = NodeJS.ReadableStream;

const c = new Client();

function streamToString(stream: ReadableStream) {
    // 将一个可读流作为流变量
    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)
    })

}
英文:

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)
})
}

答案1

得分: 0

更好的方式是使用basic-ftp模块。ftp模块非常古老,没有实现async/await功能。

所以,通过basic-ftp,您可以实现一个清晰、直接的解决方案 - 简单且易于阅读。

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()
英文:

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()

huangapple
  • 本文由 发表于 2023年2月16日 19:36:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75471695.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定