天天看點

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();
}