如何使用nodejs通过ftp下载目录的内容?

时间:2019-04-08 12:20:01

标签: node.js sftp

因此,我正在尝试使用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下载多个文件的软件包?

谢谢!

1 个答案:

答案 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版本。当然,我们需要在其中添加错误管理。