nodejs连接ftp上传下载实现方法详解【附:踩坑记录】
作者:他强任他强03
这篇文章主要介绍了nodejs连接ftp上传下载实现方法,结合实例形式详细分析了node.js使用ftp模块实现针对ftp上传、下载相关操作的方法,并附带记录了传输速度慢的解决方法,需要的朋友可以参考下
依赖
//ftp 模块是目前找到的还不错的,对于ftp的基本功能都支持 npm install ftp
连接ftp
const ftp = require('ftp');//连接FTP const client = new ftp(); client.on('ready',()=>{ console.log('ftp client is ready'); }); client.connect({ host : '***.***.***.***', port : '****', user : '***', password : '***', keepalive : 1000 });
ftp 获取列表 list
//列出目标目录 function list(dirpath){ return new Promise((resolve,reject)=>{ client.list((err,files)=>{ resolve({err : err,files : files}); }) }); } async function test (){ //list 列表功能 let {err,files} = await list(); if(err){ console.log(err); return } console.log(`获得文件列表:`+files.length); console.log(files); } test();
ftp 目录切换
//切换目录 function cwd(dirpath){ return new Promise((resolve,reject)=>{ client.cwd(dirpath,(err,dir)=>{ resolve({err : err,dir : dir}); }) }); }
FBI WARNING : 这里提醒下,在本示例中的所有代码都在同一个文件中,后面会给出完整示例代码。
有了目录切换,那么在list函数中的dirpath就可以使用啦。如下:
//列出目标目录 //列出目标目录 async function list(dirpath){ let {err : ea,dir } = await cwd(dirpath); return new Promise((resolve,reject)=>{ client.list((err,files)=>{ resolve({err : err,files : files}) }) }); }
ftp下载文件
//下载文件 async function get(filePath){ const dirpath = path.dirname(filePath); const fileName = path.basename(filePath); let {err : ea,dir} = await cwd(dirpath); return new Promise((resolve,reject)=>{ client.get(fileName,(err,rs)=>{ let ws = fs.createWriteStream(fileName); rs.pipe(ws); resolve({err : err}); }); }); }
ftp上传文件
//将文件上传到ftp目标地址 async function put(currentFile,targetFilePath){ const dirpath = path.dirname(targetFilePath); const fileName = path.basename(targetFilePath); const rs = fs.createReadStream(currentFile); let {err : ea,dir} = await cwd(dirpath);//此处应对err做处理 if(ea){ return Promise.resolve({err : ea}); } return new Promise((resolve,reject)=>{ client.put(rs,fileName,(err)=>{ resolve({err : err}); }) }); }
完整代码
const ftp = require('ftp');//连接FTP const path = require('path'); const client = new ftp(); const fs = require('fs'); client.on('ready',()=>{ console.log('ftp client is ready'); }); client.on('close',()=>{ console.log('ftp client has close') }); client.on('end',()=>{ console.log('ftp client has end') }); client.on('error',(err)=>{ console.log('ftp client has an error : '+ JSON.stringify(err)) }); client.connect({ host : '***',//这个就不提供啦 port : '***', user : '***', password : '***', keepalive : 1000 }); //列出目标目录 async function list(dirpath){ let {err : ea,dir } = await cwd(dirpath); return new Promise((resolve,reject)=>{ client.list((err,files)=>{ resolve({err : err,files : files}) }) }); } //切换目录 function cwd(dirpath){ return new Promise((resolve,reject)=>{ client.cwd(dirpath,(err,dir)=>{ resolve({err : err,dir : dir}); }) }); } //下载文件 async function get(filePath){ const dirpath = path.dirname(filePath); const fileName = path.basename(filePath); let {err : ea,dir} = await cwd(dirpath); return new Promise((resolve,reject)=>{ client.get(fileName,(err,rs)=>{ let ws = fs.createWriteStream(fileName); rs.pipe(ws); resolve({err : err}); }); }); } //将文件上传到ftp目标地址 async function put(currentFile,targetFilePath){ const dirpath = path.dirname(targetFilePath); const fileName = path.basename(targetFilePath); const rs = fs.createReadStream(currentFile); let {err : ea,dir} = await cwd(dirpath);//此处应对err做处理 if(ea){ return Promise.resolve({err : ea}); } return new Promise((resolve,reject)=>{ client.put(rs,fileName,(err)=>{ resolve({err : err}); }) }); } async function test (){ //list 列表功能 let {err,files} = await list('/attachment/byycampus/resource'); if(err){ console.log(err); return } console.log(`获得文件列表:`+files.length); console.log(files); //下载文件 let {err : ea} = await get('/attachment/byycampus/resource/201812/14/201812141035222541381967.jpg'); if(ea){ console.log(ea); return; } console.log('文件下载成功') //文件上传 let {err : eb} = await put('201812141035222541381967.jpg','/attachment/a.jpg'); if(eb){ console.log(eb); return; } console.log('文件上传成功') } test();
踩坑记录:
笔者测试过程中发现,有的ftp服务器传输速度正常,而有的ftp服务器传输速度则是非常慢!慢到平均一张十几K的图片都能传十几秒的程度!经过检查发现,这类ftp是采用的被动连接模式。
对此,查找github官方文档https://github.com/mscdex/node-ftp , 发现connect
函数中有一个pasvTimeout
选项涉及到被动连接超时设置,于是笔者测试了一下,将上面的连接代码改成如下:
const ftp = require('ftp');//连接FTP const client = new ftp(); client.on('ready',()=>{ console.log('ftp client is ready'); }); client.connect({ host : '***.***.***.***', port : '****', user : '***', password : '***', keepalive : 1000, pasvTimeout:1000 });
再次测试,传输速度慢的问题得到解决!