如何使用nodejs ssh2-sftp-client发送(放入)多个文件?

时间:2018-05-25 03:45:53

标签: node.js

如果我尝试了超过10个文件,我收到了警告,但其他文件没有上传,我无法上传超过10个文件。我做错了什么?

  

{node:17472)MaxListenersExceededWarning:可能的EventEmitter   检测到内存泄漏。增加了11名准备好的听众。使用   emitter.setMaxListeners()增加限制(节点:17472)   MaxListenersExceededWarning:可能的EventEmitter内存泄漏   检测。添加了11个错误监听器。使用emitter.setMaxListeners()来   增加限制(节点:17472)MaxListenersExceededWarning:可能   检测到EventEmitter内存泄漏。 11位接近的听众补充道。使用   emitter.setMaxListeners()增加限制}

 let Client = require('ssh2-sftp-client');
    let sftp = new Client();
    var promises = [];
    for(var i=0; i < 12; i++) {
        promises.push(sendFile(sftp, req.body, results.romlist[i].filename));
    }
    Promise.all(promises).then(function() {
        sftp.end();
        res.send('{"message":"OK"}');
    });
      const sendFile = (sftp, config, filename) => {
console.log(filename);
return sftp.connect(config).then(() => {
    return sftp.put(filename, "/home/pi/RetroPie/roms/atari2600/" + filename.substr(filename.lastIndexOf('/')+1));
}).catch((err) => {
    console.log(err, 'catch error');
});};

3 个答案:

答案 0 :(得分:2)

下面的代码使用es6-promise-pool作为示例,它对我有用:

首先需要安装es6-promise-pool:

npm install es6-promise-pool --save

代码:

let Client = require('ssh2-sftp-client');
let PromisePool = require('es6-promise-pool');

var files = [ (list of files to transfer) ]; // results.romlist[i].filename
var config = { (sftp config) };

const sendFile = (config, filename) => {
    return new Promise(function (resolve, reject) {
    let sftp = new Client();
    console.log(filename);
    sftp.on('keyboard-interactive', (name, instructions, instructionsLang, prompts, finish) => { finish([config.password]); });
    sftp.connect(config).then(() => {
        return sftp.put("(local path)" + filename, "/home/pi/RetroPie/roms/atari2600/" + filename);
    }).then(() => {
        console.log('finish '+filename);
        sftp.end();
        resolve(filename);
    }).catch((err) => {
        console.log(err, 'catch error');
    });
  });
};

var count = 0;
var sendFileProducer = function () {
    console.log("count="+count);
    if (count < 100) {
        count++;
        return(sendFile(config, files[count]));     
    } else {
        return null;
    }
}

// The number of promises to process simultaneously.
var concurrency = 10;

// Create a pool.
var pool = new PromisePool(sendFileProducer, concurrency)

pool.start().then(function () {
    console.log({"message":"OK"}); // res.send('{"message":"OK"}');
});

代码未针对网络流量进行优化,因为它为每个文件启动SFTP。但是,它仍然非常有效,因为您可以控制适合不同情况的并发性。

答案 1 :(得分:0)

这对我有用: https://github.com/theophilusx/ssh2-sftp-client/issues/73

const putFiles = (sftpConfig, fileList) => {
  const sftp = new sftpClient()
  return new Promise(function(resolve, reject) {
    sftp
    .connect(sftpConfig)
    .then(() => {
      return Promise.all(fileList.map(args => {
        return sftp.put.apply(sftp, args)
      }))
    })
    .then(() => sftp.end())
    .then(resolve)
    .catch(reject)
  });
}

答案 2 :(得分:0)

npm软件包“ sftp-upload ”对我有用,可以将目录中的10多个文件上传到远程服务器。 您可以参考以下内容:https://www.npmjs.com/package/sftp-upload

请在我测试过的nodejs中找到以下示例代码,它将可以正常工作。请用您所需的数据替换字段:

  • 用户名:sftp服务器的用户名。

  • 路径:包含要上传到服务器的文件的目录(在本地系统中)的路径。

  • remoteDir :远程目录中要上传文件的路径。

var SftpUpload = require('sftp-upload');
var fs = require('fs');
         
       sftp2 = new SftpUpload({
            host:'remote ip address',
            username:'username',
            password:'****',
            path: '/user/Desktop/test1',
            remoteDir: '/user/Desktop/test1',
            excludedFolders: ['**/.git', 'node_modules'],
            exclude: ['.gitignore', '.vscode/tasks.json'],
            dryRun: false
        });
     
        sftp2.on('error', function(err) {
            throw err;
        })
        .on('uploading', function(progress) {
            console.log('Uploading', progress.file);
            console.log(progress.percent+'% completed');
        })
        .on('completed', function() {
            console.log('Upload Completed');
        })
        .upload();

此代码会将本地系统中“ test1”目录中存在的所有文件复制到远程服务器中的“ test1”目录中。如果远程服务器中不存在“ test1”目录,则会自动创建该目录并复制文件。

如果“ test1”目录中有子文件夹,那么该子文件夹及其内容也将被复制到远程计算机上。