Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用node.js从FTP下载文件_Javascript_Node.js_Ftp - Fatal编程技术网

Javascript 使用node.js从FTP下载文件

Javascript 使用node.js从FTP下载文件,javascript,node.js,ftp,Javascript,Node.js,Ftp,我尝试将文件从远程FTP服务器下载到本地文件夹,并使用FTPmodule: var unzipper = require('unzipper'); var Client = require('ftp'); var c = new Client(); //init ftp client var connectionProperties = { host: "ftp.someurl.com", user: "user", password: "past", }; c.c

我尝试将文件从远程FTP服务器下载到本地文件夹,并使用
FTP
module:

var unzipper = require('unzipper');
var Client = require('ftp');

var c = new Client(); //init ftp client
var connectionProperties = { 
    host: "ftp.someurl.com",
    user: "user",
    password: "past",
};

c.connect(connectionProperties);

c.list('ftp/folder',function (err, list) {
  list.map((element,i)=>{
    c.get(element.name, function (err, stream) { //get file from ftp
      if (err) throw err;
      stream.pipe(unzipper.Extract({path:'local/folder/'+element.name})).promise().then((i)=>{
        console.log('File '+element.name+' unziped');
      })
      stream.once('close', function() {
        c.end();
      });
    })
  })
  if(i==element.length-1) {
    console.log('Done!');
    c.end();
  }
})
但是对于
列表中的许多文件
我有连接错误:

Error: Unable to make data connection
    at Socket.<anonymous> (/Users/user/node_test/node_modules/ftp/lib/connection.js:935:10)
    at Object.onceWrapper (events.js:285:13)
    at Socket.emit (events.js:202:15)
    at Object.cb (/Users/user/node_test/node_modules/ftp/lib/connection.js:575:18)
    at Parser.<anonymous> (/Users/user/node_test/node_modules/ftp/lib/connection.js:117:20)
    at Parser.emit (events.js:197:13)
    at Parser._write (/Users/user/node_test/node_modules/ftp/lib/parser.js:59:10)
    at doWrite (_stream_writable.js:415:12)
    at writeOrBuffer (_stream_writable.js:399:5)
    at Parser.Writable.write (_stream_writable.js:299:11)
    at Socket.ondata (/Users/user/node_test/node_modules/ftp/lib/connection.js:273:20)
    at Socket.emit (events.js:197:13)
    at addChunk (_stream_readable.js:288:12)
    at readableAddChunk (_stream_readable.js:269:11)
    at Socket.Readable.push (_stream_readable.js:224:10)
    at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:145:17)

节点ftp可用的示例与上面的示例截然不同:。听起来你是在连接可用之前呼叫列表的。客户端实例触发了一个
ready
事件,您应该将列表包装在其中。另外,我会在它们之间添加一个超时。另外,为什么要使用
地图
?这个构造也很有用。但有时我喜欢连接错误。什么函数对于列表数组更有用?forEach?看起来这会尝试同时下载文件夹中的所有文件。你有足够的联系吗?它是在第一次迭代中失败还是在文件列表中失败?@James下载多个文件后发生连接错误。随机。有时在5-6个文件之后。有时在15个文件之后。有时所有文件都会下载。但在最后的脚本中,我需要下载500多个文件。@DanMishin我认为在Map回调中处理异步操作不是一个好的做法。想想看:您正在连续执行许多异步请求。此外,
map
覆盖返回新转换数组的数组值,这就是您现在想要的。您应该执行异步循环,可以是顺序循环,也可以是并行循环,并具有最大数量的调用,这样您就不会进行太多的并行调用。
var fs = require('fs');
var unzipper = require('unzipper');
var async = require('async');
var Client = require('ftp');

//FTP Init
var c = new Client(); //init ftp client
var connectionProperties = { 
  host: "ftp.server.com",
  user: "user",
  password: "pass",
};

c.connect(connectionProperties);

var folders=['folder1','folder2','folder3','folder4','folder5'];

//Get folder file list
var listFile = function(ftp_files_folder){
  return new Promise(function(resolve, reject){
    c.list(ftp_files_folder,function (err, list) {
      if (err) reject(err)
      resolve(list)
    })
  })
}

//Get and unzipfiles from all folders
async.mapLimit(folders, 1, function(folder, callback){
    var local_folder=__dirname+folder;
    var ftp_files_folder=folder;

    listFile(ftp_files_folder).then((paths)=>{
        console.log('Checking files for: '+folder);
        async.mapLimit(paths, 1, function(file, callback){
            var file_type='.xml';
        var ftp_file_path=ftp_files_folder+'/'+file; //get ftp path to file
        var local_file_path=local_folder+'/'+file; //get local path to file
        var local_subfolder=local_file_path.split(file_type).shift(); //get local subfolder name
        if(!fs.existsSync(local_subfolder)){
            c.get(ftp_file_path, function (err, stream) {
                if(err){
                console.log('Error getting ' + element)
                callback(err)
              }else{
                stream.pipe(unzipper.Extract({path: local_subfolder})).on('finish', ()=>{
                      console.log('==File '+file+' unziped==');
                      callback();
                  })
              }
            })
          } else {
              callback();
          }
      }, function(err, res){
        if(err) console.log(err)
        console.log('Updates for '+folder+' complete');
        callback();
      })
    })
}, function(err, res){
  if(err) console.log(err);
  if(res.length==folders.length) c.end();
  console.log('Done!');
})