Javascript 使用node.js从FTP下载文件
我尝试将文件从远程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
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!');
})