因此,我正在尝试使用nodejs通过sftp下载目录的内容,到目前为止,我一直陷入错误。
我正在使用ssh2-sftp-client npm软件包,并且在大多数情况下它运行良好,因为我能够连接到服务器并在特定的远程目录中列出文件。
使用fastGet方法下载文件也没有任何麻烦,并且由于所有方法都是基于承诺的,所以我认为我可以通过执行以下操作轻松地下载目录中的所有文件:
let main = async () => {
await sftp.connect(config.sftp);
let data = await sftp.list(config.remote_dir);
if (data.length) data.map(async x => {
await sftp.fastGet(`${config.remote_dir}/${x.name}`, config.base_path + x.name);
});
}
因此,上面的代码成功下载了第一个文件,但随后崩溃并显示以下错误消息:
错误:无法获取沙箱/demo2.txt:由于正在进行文件传输,因此无法执行请求的操作。
这似乎表明fastGet的承诺解决得太早了,因为在处理文件列表的下一个元素时文件传输应该已经结束。
我尝试使用更传统的get()代替,但是它正在使用流,并且失败并显示其他错误。经过研究,似乎在节点10.x中的流方面发生了重大变化。就我而言,调用get完全失败(甚至没有下载第一个文件)。
有人知道解决方法吗?否则,另一个可以通过sftp下载多个文件的软件包?
谢谢!
答案 0 :(得分:0)
我发现,由于问题是同时尝试在一个客户端连接上进行下载,因此我可以尝试在每个文件下载中使用一个客户端进行管理。我最终得到了以下递归函数。
let getFromFtp = async (arr) => {
if (arr.length == 0) return (processFiles());
let x = arr.shift();
conns.push(new Client());
let idx = conns.length - 1;
await conns[idx].connect(config.sftp.auth);
await conns[idx]
.fastGet(`${config.sftp.remote_dir}/${x.name}`, `${config.dl_dir}${x.name}`);
await connections[idx].end();
getFromFtp(arr);
};
有关此功能的注意事项:
array参数是要下载的文件的列表,大概是事先使用list()获取的。
conns被声明为空数组,用于包含我们的客户。
使用array.prototype.shift()在我们浏览文件列表时逐渐耗尽数组
processFiles()方法。
这只是POC版本。当然,我们需要在其中添加错误管理。