今天小编给大家分享一下node ftp怎么上传文件夹到服务器的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
完整代码示例如下:
const ftp = require('ftp');//连接FTPconst path = require('path');const client = new ftp();const fs = require('fs');//本地文件夹路径;const localDirPath = '/test/';//远程地址,打开ftp以后的地址,不需要加入host;const remotePath = '/';const uploadFiles = [];const mkDirPromiseArr = [];const connectionProperties = { host: '', //ftp地址; user: '', //用户名; password: '', //密码; port: 21 //端口;};client.connect(connectionProperties);client.on('ready', () => { console.log('ftp client is ready'); start();});async function start() { const { err: ea, dir } = await cwd(remotePath);//此处应对err做处理 if (ea) { client.mkdir(remotePath, true, (err) => { if (err) { console.log('创建' + remotePath + '文件夹失败'); upload(); } else { console.log('创建' + remotePath + '成功'); upload(); } }); } else { upload(); } function upload() { const filesPath = { files: [] }; getDirAllFilePath(localDirPath, filesPath); remoteMkDir(filesPath, ''); console.log('准备上传...'); setTimeout(() => { Promise.all(mkDirPromiseArr).then(() => { console.log('开始上传...'); const tasks = uploadFile(); runPromiseArray(tasks).then(() => { client.end(); console.warn('上传完成~'); }); }); }, 3000); }}// 获取本地的文件地址和路径;function getDirAllFilePath(paths, parent) { const files = fs.readdirSync(paths); files.forEach(item => { if (item != '.DS_Store') { const path = `${paths}/${item}`; if (isDir(path)) { getDirAllFilePath(path, parent[item] = { files: [] }); } else if (isFile(path)) { parent.files.push(item); } } })}//创建远程确实的文件夹;async function remoteMkDir(obj, _path) { for (const key in obj) { if (key === 'files') { for (let i = 0, len = obj[key].length; i < len; i++) { const promise = new Promise(async resolve => { let p = ''; if (_path) { p = _path + '/'; } const filePathName = p + obj[key][i]; uploadFiles.push({ path: filePathName, fileName: obj[key][i] }); const ph = remotePath + filePathName.substring(0, filePathName.lastIndexOf('/') + 1); let { err: ea, dir } = await cwd(ph);//此处应对err做处理 if (ea) { client.mkdir(ph, true, (err) => { if (err) { console.log('mkdir' + ph + 'err', err); resolve(null); return; } console.log('mkdir ' + ph + ' success'); resolve(null); }); } else { resolve(null); } }); mkDirPromiseArr.push(promise); } } else { let p = ''; if (_path) { p = _path + '/'; } remoteMkDir(obj[key], p + key); } }}//上传文件;function uploadFile() { const tasks = []; const resourcesPath = localDirPath; //目标路径文件夹; const checkPath = remotePath; for (let i = 0, len = uploadFiles.length; i < len; i++) { const task = () => { return new Promise(async (resolve, reject) => { const _path = uploadFiles[i].path; const targetPath = checkPath + _path; const putPath = resourcesPath + '/' + _path; const dirpath = path.dirname(targetPath); const fileName = path.basename(targetPath); client.cwd(dirpath, (cwdErr, dir) => { client.pwd((pwdErr, cwd) => { if (pwdErr) { resolve(pwdErr) } else { client.get(fileName, (err, res) => { if (res) { console.log(`${targetPath} =====================已经存在了`); resolve(true); } else { const rs = fs.createReadStream(putPath); client.put(rs, fileName, (putErr, data) => { if (putErr) { resolve(err); } else { console.log(targetPath + '文件上传成功'); resolve(true); } }) } }); } }); }) }); } tasks.push(task); } return tasks;}//执行Promise的队列动作;function runPromiseArray(parray) { //这个方法可以放到G里 let p = Promise.resolve(); for (let promise of parray) { p = p.then(promise); } return p;}//切换目录async function cwd(dirpath) { return new Promise((resolve, reject) => { client.cwd(dirpath, (err, dir) => { resolve({ err: err, dir: dir }); }) });}function isFile(filepath) { //判断是否是文件 Boolean let stat = fs.statSync(filepath) return stat.isFile()}function isDir(filepath) { //判断是否是文件夹 Boolean let stat = fs.statSync(filepath); return stat.isDirectory();}
笔者解读一下:代码中的localDirPath为本地需要读取其中文件,并使用ftp上传的文件夹。
注意:这里的上传是针对文件夹中所有的文件夹与文件进行遍历后的上传,实际应用中,我们可能只需要上传指定的文件,对此,笔者修改后的脚本如下:
const ftp = require('ftp');//连接FTPconst path = require('path');const client = new ftp();const fs = require('fs');//本地文件夹路径;const localDirPath = path.join(__dirname,'/imgtmp/');//待遍历的本地目录//远程ftp服务器文件路径let remotePath = '/yourweb/images/';const upFileList = ["202304/202304061415075072.png","202304/202304061415075073.png"];//手动设置需要上传的文件const uploadFiles = [];const mkDirPromiseArr = [];client.on('ready',()=>{ console.log('ftp client is ready');});const connconfig = { host: '', //ftp地址; user: '', //用户名; password: '', //密码; port: 21 //端口;}client.connect(connconfig);client.on('ready', () => { console.log('ftp client is ready'); start();}); async function start() { const { err: ea, dir } = await cwd(remotePath);//此处应对err做处理 if (ea) { client.mkdir(remotePath, true, (err) => { if (err) { console.log('创建' + remotePath + '文件夹失败'); upload(); } else { console.log('创建' + remotePath + '成功'); upload(); } }); } else { upload(); } function upload() { console.log("mkDirPromiseArr==>",mkDirPromiseArr); // const filesPath = { files: [] }; // getDirAllFilePath(localDirPath, filesPath); const filesPath = { files: upFileList };//直接给定需要上传的文件列表 // console.log("遍历之后的filesPath===>",filesPath); remoteMkDir(filesPath, ''); console.log('准备上传...'); setTimeout(() => { Promise.all(mkDirPromiseArr).then(() => { console.log('开始上传...'); const tasks = uploadFile(); runPromiseArray(tasks).then(() => { client.end(); console.warn('上传完成~'); }); }); }, 1000); }} // 获取本地的文件地址和路径;function getDirAllFilePath(paths, parent) { const files = fs.readdirSync(paths); files.forEach(item => { if (item != '.DS_Store') { const path = `${paths}/${item}`; if (isDir(path)) { getDirAllFilePath(path, parent[item] = { files: [] }); } else if (isFile(path)) { parent.files.push(item); } } })} //创建远程缺失的文件夹;async function remoteMkDir(obj, _path) { for (const key in obj) { if (key === 'files') { for (let i = 0, len = obj[key].length; i < len; i++) { const promise = new Promise(async resolve => { let p = ''; if (_path) { p = _path + '/'; } const filePathName = p + obj[key][i]; // const filePathName = path.dirname(obj[key][i]); const fileName = path.basename(obj[key][i]); // uploadFiles.push({ path: filePathName, fileName: obj[key][i] }); uploadFiles.push({ path: filePathName, fileName: fileName }); const ph = remotePath + filePathName.substring(0, filePathName.lastIndexOf('/') + 1); let { err: ea, dir } = await cwd(ph);//此处应对err做处理 if (ea) { client.mkdir(ph, true, (err) => { if (err) { console.log('mkdir' + ph + 'err', err); resolve(null); return; } console.log('mkdir ' + ph + ' success'); resolve(null); }); } else { resolve(null); } }); mkDirPromiseArr.push(promise); } } else { let p = ''; if (_path) { p = _path + '/'; } remoteMkDir(obj[key], p + key); } }} //上传文件;function uploadFile() { const tasks = []; const resourcesPath = localDirPath; //目标路径文件夹; const checkPath = remotePath; for (let i = 0, len = uploadFiles.length; i < len; i++) { const task = () => { return new Promise(async (resolve, reject) => { const _path = uploadFiles[i].path; // const _path = uploadFiles[i]; const targetPath = checkPath + _path; const putPath = resourcesPath + '/' + _path; const dirpath = path.dirname(targetPath); const fileName = path.basename(targetPath); client.cwd(dirpath, (cwdErr, dir) => { client.pwd((pwdErr, cwd) => { if (pwdErr) { resolve(pwdErr) } else { client.get(fileName, (err, res) => { if (res) { console.log(`${targetPath} =====================已经存在了`); resolve(true); } else { const rs = fs.createReadStream(putPath); client.put(rs, fileName, (putErr, data) => { if (putErr) { resolve(err); } else { console.log(targetPath + '文件上传成功'); resolve(true); } }) } }); } }); }) }); } tasks.push(task); } return tasks;} //执行Promise的队列动作;function runPromiseArray(parray) { //这个方法可以放到G里 let p = Promise.resolve(); for (let promise of parray) { p = p.then(promise); } return p;} //切换目录async function cwd(dirpath) { return new Promise((resolve, reject) => { client.cwd(dirpath, (err, dir) => { resolve({ err: err, dir: dir }); }) });} function isFile(filepath) { //判断是否是文件 Boolean let stat = fs.statSync(filepath) return stat.isFile()} function isDir(filepath) { //判断是否是文件夹 Boolean let stat = fs.statSync(filepath); return stat.isDirectory();}
以上就是“node ftp怎么上传文件夹到服务器”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。