[转] java 通过SSH方式连接远程主机并上传和下载文件

 Java连接远程主机的方式有多种,这里和大家分享的是通过ssh方式连接远程主机,使用的是jsch这个jar包,资源在这里。

    不懂ssh为何物的朋友可以从网上找找相关资料,这里只简单的解释下:SSH 为 Secure Shell(安全外壳协议) 的缩写,由 IETF 的网络工作小组(Network Working Group)所制定,为建立在应用层和传输层基础上的安全协议。SSH在传输层提供服务器认证,数据机密性,信息完整性等的支持,并为服务器提供客户端的身份鉴别。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。通过SSH可以对所有传输的数据进行加密,也能够防止DNS欺骗和IP欺骗。

    下面是自己写的一个sftp帮助类,代码中有错误或者是不合理完善的地方希望能够指出,共同学习成长:

package com.app.pt.backup.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.app.common.util.FileUtil;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

/**
 * SFTP帮助类
 * @author wangbailin
 *
 */
public class SFTPUtil {
	
	private static Log log = LogFactory.getLog(SFTPUtil.class);
	
	/**
	 * 连接sftp服务器
	 * @param host 远程主机ip地址
	 * @param port sftp连接端口,null 时为默认端口
	 * @param user 用户名
	 * @param password 密码
	 * @return
	 * @throws JSchException 
	 */
	public static Session connect(String host, Integer port, String user, String password) throws JSchException{
		Session session = null;
		try {
			JSch jsch = new JSch();
			if(port != null){
				session = jsch.getSession(user, host, port.intValue());
			}else{
				session = jsch.getSession(user, host);
			}
			session.setPassword(password);
			//设置第一次登陆的时候提示,可选值:(ask | yes | no)
			session.setConfig("StrictHostKeyChecking", "no");
			//30秒连接超时
			session.connect(30000);
		} catch (JSchException e) {
			e.printStackTrace();
			System.out.println("SFTPUitl 获取连接发生错误");
			throw e;
		}
		return session;
	}
	
	/**
	 * sftp上传文件(夹)
	 * @param directory
	 * @param uploadFile
	 * @param sftp
	 * @throws Exception 
	 */
	public static void upload(String directory, String uploadFile, ChannelSftp sftp) throws Exception{
		System.out.println("sftp upload file [directory] : "+directory);
		System.out.println("sftp upload file [uploadFile] : "+ uploadFile);
		File file = new File(uploadFile);
		if(file.exists()){
			//这里有点投机取巧,因为ChannelSftp无法去判读远程linux主机的文件路径,无奈之举
			try {
				Vector content = sftp.ls(directory);
				if(content == null){
					sftp.mkdir(directory);
				}
			} catch (SftpException e) {
				sftp.mkdir(directory);
			}
			//进入目标路径
			sftp.cd(directory);
			if(file.isFile()){
				InputStream ins = new FileInputStream(file);
				//中文名称的
				sftp.put(ins, new String(file.getName().getBytes(),"UTF-8"));
				//sftp.setFilenameEncoding("UTF-8");
			}else{
				File[] files = file.listFiles();
				for (File file2 : files) {
					String dir = file2.getAbsolutePath();
					if(file2.isDirectory()){
						String str = dir.substring(dir.lastIndexOf(file2.separator));
						directory = FileUtil.normalize(directory + str);
					}
					upload(directory,dir,sftp);
				}
			}
		}
	}
	
	/**
	 * sftp下载文件(夹)
	 * @param directory 下载文件上级目录
	 * @param srcFile 下载文件完全路径
	 * @param saveFile 保存文件路径
	 * @param sftp ChannelSftp
	 * @throws UnsupportedEncodingException
	 */
	public static void download(String directory,String srcFile, String saveFile, ChannelSftp sftp) throws UnsupportedEncodingException {
		Vector conts = null;
		try{
			conts = sftp.ls(srcFile);
		} catch (SftpException e) {
			e.printStackTrace();
			log.debug("ChannelSftp sftp罗列文件发生错误",e);
		}
		File file = new File(saveFile);
		if(!file.exists()) file.mkdir();
		//文件
		if(srcFile.indexOf(".") > -1){
			try {
				sftp.get(srcFile, saveFile);
			} catch (SftpException e) {
				e.printStackTrace();
				log.debug("ChannelSftp sftp下载文件发生错误",e);
			}
		}else{
		//文件夹(路径)
			for (Iterator iterator = conts.iterator(); iterator.hasNext();) {
				LsEntry obj =  (LsEntry) iterator.next();
				String filename = new String(obj.getFilename().getBytes(),"UTF-8");
				if(!(filename.indexOf(".") > -1)){
					directory = FileUtil.normalize(directory + System.getProperty("file.separator") + filename);
					srcFile = directory;
					saveFile = FileUtil.normalize(saveFile + System.getProperty("file.separator") + filename);
				}else{
					//扫描到文件名为".."这样的直接跳过
					String[] arrs = filename.split("\\.");
					if((arrs.length > 0) && (arrs[0].length() > 0)){
						srcFile = FileUtil.normalize(directory + System.getProperty("file.separator") + filename);
					}else{
						continue;
					}
				}
				download(directory, srcFile, saveFile, sftp);
			}
		}
	}
}

  使用sftp帮助类上传或下载:

ChannelSftp sftp = null;
Session session = null;
try {
	session = SFTPUtil.connect(host, port, username, password);
	Channel channel = session.openChannel("sftp");
	channel.connect();
	sftp = (ChannelSftp) channel;
	SFTPUtil.upload(destDir, srcfile.getAbsolutePath(), sftp);
} catch (Exception e) {
	e.printStackTrace();
	logger.debug(e);
	return UtilMisc.toMap("flag","failure","msg","备份文件到远程主机发生错误");
}finally{
	if(sftp != null)sftp.disconnect();
	if(session != null)session.disconnect();
}

 (转自:http://blog.csdn.net/wangbailin2009/article/details/20232999

猜你喜欢

转载自krs.iteye.com/blog/2338449