【问题标题】:SFTP modules in Node to download and delete filesNode中用于下载和删除文件的SFTP模块
【发布时间】:2017-01-14 09:46:12
【问题描述】:

我的任务很简单(或者更好,应该是):从 Node 应用程序获取 SFTP 中目录的内容,然后下载其中的所有文件,最后远程删除它们。

现在,我检查了不同的模块。在我看来,非常干净的是 ssh2-sftp-client。我可以这样使用它:

let Client = require('ssh2-sftp-client');
let sftp = new Client();

sftp.connect({
    host: myhost,
    port: '22',
    username: myusername,
    password: mypassword
}).then(() => {
    return sftp.list('/path/to/my/files');
}).then((data) => {

    for(var i = 0 ; i < data.length; i++) {
        sftp.get('/path/to/my/files/'+data[i].name); 
        }   
}).catch((err) => {
    console.log(err, 'catch error');
});

我可以列出所有文件并在控制台中查看生成的 jSon,但 .get 命令似乎什么也没做,我不知道出了什么问题。从文档 (https://www.npmjs.com/package/ssh2-sftp-client) 中,您可以像我一样简单地获取文件。但是:

1) 它似乎不起作用 2)我怎样才能调试发生了什么? 3)如果我没有机会选择本地目录,这些文件很可能会在node启动js的地方下载,对吗?

那么,如果使用此模块(或其他模块,如果有的话)成功下载了文件,我如何才能获得实际下载并可能远程删除的文件?

谢谢, 法比奥

【问题讨论】:

  • sftp.get('/path/to/my/files/'+data[i].name) 返回一个流。您必须处理该流并将其保存为本地计算机中的文件。
  • 谢谢,你能告诉我我可以用来完成这个任务的 sftp 命令,即处理流吗?即使模块没有实现它,我也可以使用 ssh2 基本模块方法。
  • 好的...我可以帮你。要将流保存为文件吗?

标签: node.js sftp


【解决方案1】:

sftp.get() 返回一个返回流的 Promise,因此如果要将流保存到磁盘,则需要通过管道传输。例如:

var fs = require('fs');

// ...

for(var i = 0; i < data.length; i++) {
  const remoteFilename = '/path/to/remote/files/' + data[i].name;
  const localFilename = '/path/to/local/files/' + data[i].name;
  sftp.get(remoteFilename).then((stream) => {
    stream.pipe(fs.createWriteStream(localFilename));
  });
}

此外,ssh2-sftp-client 似乎没有使用 ssh2 模块的最新版本分支(在撰写本文时为 v0.5.x),所以如果您遇到问题,请记住这一点。

【讨论】:

  • 它给了我: TypeError: sftp.get(...).pipe is not a function。但是我理解你的解决方案,我会进一步调查。谢谢!!!
  • 好的,所以模块的文档是错误的/误导性的。它实际上返回一个返回流的 Promise(相当奇怪,因为获取文件流没有任何异步)。
  • 我明白了,是的,有时文档真的很差。很遗憾。我快到了,虽然 get 和 pipe 打破了 for 循环,实际上只下载了最后一个文件。 'for(var i = 0 ; i { console.log(i); stream.pipe(fs.createWriteStream(localFilename)); }); }' 其中第一个控制台打印 0,1,2,3,4,5,而第二个控制台打印 6 次 5。
  • 现在一切正常!我不得不听从你的建议,将路径声明为 const 而不是 var。
  • @FabioRicci 你能发布你的最终代码吗?我遇到了类似的问题,很想有个起点。
【解决方案2】:
sftp.get(remoteFileNameWithPath, true).then(stream => {
  stream.pipe(fs.createWriteStream(localFilePath)).on('close', () => console.log('completely passed file'))
})

get 方法返回一个带有流结果的 Promise,因此,为了保存它,您需要通过管道传输到 writeStream 查看 nodejs 上的文档:https://nodejs.org/api/stream.html

【讨论】:

    【解决方案3】:

    使用 get() 方法下载并保存文件

    sftp.get(remote_file_path, local_file_path).then((stream) => {
        console.log('File download Success')
    }); 

    它需要两个参数:src 和 dest 文件路径

    【讨论】:

      【解决方案4】:

      我不确定会发生什么,但是当我运行这样的代码时,它只会下载一个文件。

      for (var i = fileList.length - 1; i >= 0; i--) {
      
        remoteFilename = process.env.FTP_DEFAULT_DIR + '/' + fileList[i].name
        localFilename = fileList[i].name
      
        sftp.get(remoteFilename).then((stream) => {
          stream.pipe(fs.createWriteStream(localFilename));
          console.log(stream);
          console.log('processing: ', remoteFilename);
        }).catch((err)=> {
          console.log(err)
        });
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-06
        • 2017-10-06
        • 2011-08-14
        相关资源
        最近更新 更多