英文:
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()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论