nodejs ssh2基本功能封装,实现上传、下载文件以及文件夹

来源:互联网 发布:linux log4j日志乱码 编辑:程序博客网 时间:2024/06/04 23:33

最新封装见:http://blog.csdn.net/llmys/article/details/52997924

最近在做自动化测试的时候,需要用到nodejs ssh2模块将windows上的文件传到linux机器上,由于网上别人封装的ssh2-util模块实在不好用,不是下载文件夹之后无法退出,就是下载不下来。可能是我自己用法不对的缘故,由于我没有学过JS,很多不懂,所有用ssh2更加不好用,每次我都想说一句:"好恼火"。

好了,吐槽完毕,接下来写写我封装的基本功能。仅仅实现了运行linux的shell命令、上传文件、下载文件、上传文件夹、下载文件夹。

上传文件夹思路:首先获取本地机器文件目录下的子目录列表以及文件名列表,再通过调用shell函数执行mkdir命令在linux机器上面创建文件夹,然后再一个一个的上传文件。

下载文件夹思路:首先获取远程linux机器目录下的子目录列表以及文件名列表,再在本地机器上创建文件夹,再将文件一个一个的下载下来。

也许是我没有学过JS、Node.js的缘故,每次用同一个连接下来多个文件就会出问题,并发多了就出现问题了,希望会的人可以给我指点一下思路,或者给我说一下应该怎么使用。所有在我的代码中我都是等待ssh的操作一个一个的完成之后再去执行其他操作。

"use strict"var ssh2 = require("ssh2");var util=require("util")var events=require("events");var Client = require("ssh2").Client;var fs = require("fs");var path = require('path');var async = require('async');/*** 描述:连接远程电脑* 参数:server 远程电脑凭证;then 回调函数* 回调:then(conn) 连接远程的client对象*/function Connect(server, then){var conn = new Client();conn.on("ready", function(){then(conn);}).on('error', function(err){//console.log("connect error!");}).on('end', function() {//console.log("connect end!");}).on('close', function(had_error){//console.log("connect close");}).connect(server);}/*** 描述:运行shell命令* 参数:server 远程电脑凭证;cmd 执行的命令;then 回调函数* 回调:then(err, data) : data 运行命令之后的返回数据信息*/function Shell(server, cmd, then){Connect(server, function(conn){conn.shell(function(err, stream){if(err){then(err);}else{// end of ifvar buf = "";stream.on('close', function(){conn.end();then(err, buf);}).on('data', function(data){buf=buf+data;}).stderr.on('data', function(data) {console.log('stderr: ' + data);});stream.end(cmd);}});});}/*** 描述:上传文件* 参数:server 远程电脑凭证;localPath 本地路径;remotePath 远程路径;then 回调函数* 回调:then(err, result)*/function UploadFile(server, localPath, remotePath , then){Connect(server, function(conn){conn.sftp(function(err, sftp){if(err){then(err);}else{sftp.fastPut(localPath, remotePath, function(err, result){conn.end();then(err, result);});}});});}/*** 描述:下载文件* 参数:server 远程电脑凭证;remotePath 远程路径;localPath 本地路径;then 回调函数* 回调:then(err, result)*/function DownloadFile(server, remotePath, localPath, then){Connect(server, function(conn){conn.sftp(function(err, sftp){if(err){then(err);}else{sftp.fastGet(remotePath, localPath, function(err, result){if(err){then(err);}else{conn.end();then(err, result);}});}});});}/*** 描述:获取远程文件路径下文件列表信息* 参数:server 远程电脑凭证;*remotePath 远程路径;*isFile 是否是获取文件,true获取文件信息,false获取目录信息;*then 回调函数* 回调:then(err, dirs) : dir, 获取的列表信息*/function GetFileOrDirList(server, remotePath, isFile, then){var cmd = "find " + remotePath + " -type "+ (isFile == true ? "f":"d") + "\r\nexit\r\n";Shell(server, cmd, function(err, data){var arr = [];var remoteFile = [];arr = data.split("\r\n");arr.forEach(function(dir){if(dir.indexOf(remotePath) ==0){remoteFile.push(dir);}});then(err, remoteFile);});}/*** 描述:控制上传或者下载一个一个的执行*/function Control(){events.EventEmitter.call(this);}util.inherits(Control, events.EventEmitter); // 使这个类继承EventEmittervar control = new Control();control.on("donext", function(todos, then){if(todos.length > 0){var func = todos.shift();func(function(err, result){if(err){throw err;then(err);}else{control.emit("donext", todos, then);}});}else{then(null);}});/*** 描述:下载目录到本地* 参数:server 远程电脑凭证;*remotePath 远程路径;*localDir 本地路径,*then 回调函数* 回调:then(err)*/function DownloadDir(server, remoteDir,localDir, then){GetFileOrDirList(server, remoteDir, false, function(err, dirs){if(err){throw err;}else{GetFileOrDirList(server, remoteDir, true, function(err, files){if(err){throw err;}else{dirs.shift();dirs.forEach(function(dir){var tmpDir = path.join(localDir, dir.slice(remoteDir.length+1)).replace(/[//]\g/, '\\');// 创建目录fs.mkdirSync(tmpDir);});var todoFiles = [];files.forEach(function(file){var tmpPath = path.join(localDir, file.slice(remoteDir.length+1)).replace(/[//]\g/, '\\');todoFiles.push(function(done){DownloadFile(server, file, tmpPath, done);console.log("downloading the "+file);});// end of todoFiles.push});control.emit("donext", todoFiles, then);}});}});}/*** 描述:获取windows上的文件目录以及文件列表信息* 参数:destDir 本地路径,*dirs 目录列表*files 文件列表*/function GetFileAndDirList(localDir, dirs, files){var dir = fs.readdirSync(localDir);for(var i = 0; i < dir.length; i ++){var p = path.join(localDir, dir[i]);var stat = fs.statSync(p); if(stat.isDirectory()){dirs.push(p);GetFileAndDirList(p, dirs, files);}else{files.push(p);}}}/*** 描述:上传文件夹到远程目录* 参数:server 远程电脑凭证;*localDir 本地路径,*remotePath 远程路径;*then 回调函数* 回调:then(err)*/function UploadDir(server, localDir, remoteDir, then){var dirs = [];var files = [];GetFileAndDirList(localDir, dirs, files);// 创建远程目录var todoDir = [];dirs.forEach(function(dir){todoDir.push(function(done){var to = path.join(remoteDir, dir.slice(localDir.length+1)).replace(/[\\]/g, '/');var cmd = "mkdir -p " + to +"\r\nexit\r\n";console.log(cmd);Shell(server, cmd, done);})// end of push});// 上传文件var todoFile = [];files.forEach(function(file){todoFile.push(function(done){var to  = path.join(remoteDir, file.slice(localDir.length+1)).replace(/[\\]/g, '/');console.log("upload " + to);UploadFile(server, file, to, done);});});control.emit("donext", todoDir, function(err){if(err){throw err;}else{control.emit("donext", todoFile, then);}});}exports.Shell = Shell;exports.UploadFile = UploadFile;exports.DownloadFile = DownloadFile;exports.GetFileOrDirList = GetFileOrDirList;exports.DownloadDir = DownloadDir;exports.UploadDir = UploadDir;

2 0
原创粉丝点击