最代碼廣告位
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jcraft.jsch.Channel;
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;

/**
 * 利用JSch包實現SFTP下載、上傳文件的類
 * 
 * @author 
 * @version 1.0
 */
public class SftpManager {
	private static final Logger logger = LoggerFactory.getLogger(SftpManager.class);
	public static final String SFTP_PROTOCAL = "sftp";

	/**
	 * Password authorization
	 * 
	 * @param host
	 *            主機IP
	 * @param username
	 *            主機登陸用戶名
	 * @param password
	 *            主機登陸密碼
	 * @param port
	 *            主機ssh登陸端口,如果port <= 0取默認值(22)
	 * @return sftp
	 * @throws Exception
	 * @see http://www.jcraft.com/jsch/
	 */
	public static ChannelSftp connect(String host, String username, String password, int port) throws Exception {
		Channel channel = null;
		ChannelSftp sftp = null;
		JSch jsch = new JSch();

		Session session = createSession(jsch, host, username, port);
		// 設置登陸主機的密碼
		session.setPassword(password);
		// 設置登陸超時時間
		session.connect(15000);
		logger.info("Session connected to " + host + ".");
		try {
			// 創建sftp通信通道
			channel = (Channel) session.openChannel(SFTP_PROTOCAL);
			channel.connect(1000);
			logger.info("Channel created to " + host + ".");
			sftp = (ChannelSftp) channel;
		} catch (JSchException e) {
			logger.error("exception when channel create.", e);
		}
		return sftp;
	}

	/**
	 * Private/public key authorization (加密秘鑰方式登陸)
	 * 
	 * @param username
	 *            主機登陸用戶名(user account)
	 * @param host
	 *            主機IP(server host)
	 * @param port
	 *            主機ssh登陸端口(ssh port), 如果port<=0, 取默認值22
	 * @param privateKey
	 *            秘鑰文件路徑(the path of key file.)
	 * @param passphrase
	 *            密鑰的密碼(the password of key file.)
	 * @return sftp
	 * @throws Exception
	 * @see http://www.jcraft.com/jsch/
	 */
	public static ChannelSftp connect(String username, String host, int port, String privateKey, String passphrase)
			throws Exception {
		Channel channel = null;
		ChannelSftp sftp = null;
		JSch jsch = new JSch();

		// 設置密鑰和密碼 ,支持密鑰的方式登陸
		if (StringUtils.isNotEmpty(privateKey)) {
			if (StringUtils.isNotEmpty(passphrase)) {
				// 設置帶口令的密鑰
				jsch.addIdentity(privateKey, passphrase);
			} else {
				// 設置不帶口令的密鑰
				jsch.addIdentity(privateKey);
			}
		}
		Session session = createSession(jsch, host, username, port);
		// 設置登陸超時時間
		session.connect(15000);
		logger.info("Session connected to " + host + ".");
		try {
			// 創建sftp通信通道
			channel = (Channel) session.openChannel(SFTP_PROTOCAL);
			channel.connect(1000);
			logger.info("Channel created to " + host + ".");
			sftp = (ChannelSftp) channel;
		} catch (JSchException e) {
			logger.error("exception when channel create.", e);
		}
		return sftp;
	}

	/**
	 * upload all the files to the server<br/>
	 * 將本地文件名為 srcFile 的文件上傳到目標服務器, 目標文件名為 dest,<br/>
	 * 若 dest為目錄,則目標文件名將與srcFile文件名相同. 采用默認的傳輸模式: OVERWRITE
	 * 
	 * @param sftp
	 * @param srcFile
	 *            本地文件的絕對路徑
	 * @param dest
	 *            目標文件的絕對路徑
	 */
	public static void upload(ChannelSftp sftp, String srcFile, String dest) {
		try {
			File file = new File(srcFile);
			if (file.isDirectory()) {
				sftp.cd(srcFile);
				for (String fileName : file.list()) {
					sftp.put(srcFile + SystemUtils.FILE_SEPARATOR + fileName, dest);
				}
			}
			sftp.put(srcFile, dest);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * upload all the files to the server<br/>
	 * 將fileList中的本地文件上傳到目標服務器, 目標目錄路徑為 destPath,<br/>
	 * destPath必須是目錄,目標文件名將與源文件名相同. 采用默認的傳輸模式: OVERWRITE
	 * 
	 * @param sftp
	 * @param fileList
	 *            要上傳到目標服務器的文件的絕對路徑
	 * @param destPath
	 *            目標文件的絕對路徑, 一定是目錄, 如果目錄不存在則自動創建
	 * @throws SftpException
	 */
	public static void upload(ChannelSftp sftp, List<String> fileList, String destPath) throws SftpException {
		try {
			sftp.cd(destPath);
		} catch (Exception e) {
			sftp.mkdir(destPath);
		}
		for (String srcFile : fileList) {
			upload(sftp, srcFile, destPath);
		}
	}

	/**
	 * 使用sftp下載文件
	 * 
	 * @param sftp
	 * @param srcPath
	 *            sftp服務器上源文件的路徑, 必須是目錄
	 * @param saveFile
	 *            下載后文件的存儲路徑, 若為目錄, 則文件名將與目標服務器上的文件名相同
	 * @param srcfile
	 *            目標服務器上的文件, 不能為目錄
	 */
	public static void download(ChannelSftp sftp, String srcPath, String saveFile, String srcfile) {
		try {
			sftp.cd(srcPath);
			File file = new File(saveFile);
			if (file.isDirectory()) {
				sftp.get(srcfile, new FileOutputStream(file + SystemUtils.FILE_SEPARATOR + srcfile));
			} else {
				sftp.get(srcfile, new FileOutputStream(file));
			}
		} catch (Exception e) {
			logger.error("download file: {} error", srcPath + SystemUtils.FILE_SEPARATOR + srcfile, e);
		}
	}

	/**
	 * 使用sftp下載目標服務器上某個目錄下指定類型的文件, 得到的文件名與 sftp服務器上的相同
	 * 
	 * @param sftp
	 * @param srcPath
	 *            sftp服務器上源目錄的路徑, 必須是目錄
	 * @param savePath
	 *            下載后文件存儲的目錄路徑, 一定是目錄, 如果不存在則自動創建
	 * @param fileTypes
	 *            指定類型的文件, 文件的后綴名組成的字符串數組
	 */
	public static void download(ChannelSftp sftp, String srcPath, String savePath, String... fileTypes) {
		List<String> fileList = new ArrayList<String>();
		try {
			sftp.cd(srcPath);
			createDir(savePath);
			if (fileTypes.length == 0) {
				// 列出服務器目錄下所有的文件列表
				fileList = listFiles(sftp, srcPath, "*");
				downloadFileList(sftp, srcPath, savePath, fileList);
				return;
			}
			for (String type : fileTypes) {
				fileList = listFiles(sftp, srcPath, "*" + type);
				parseAndUpdateDB(sftp, srcPath, savePath, fileList);
			}
		} catch (Exception e) {
			logger.error("download all file in path = '" + srcPath + "' and type in " + Arrays.asList(fileTypes)
					+ " error", e);
		}

	}

	private static File createDir(String savePath) throws Exception {
		File localPath = new File(savePath);
		if (!localPath.exists() && !localPath.isFile()) {
			if (!localPath.mkdir()) {
				throw new Exception(localPath + " directory can not create.");
			}
		}
		return localPath;
	}

	/**
	 * sftp下載目標服務器上srcPath目錄下所有指定的文件.<br/>
	 * 若本地存儲路徑下存在與下載重名的文件,仍繼續下載并覆蓋該文件.<br/>
	 * 
	 * @param sftp
	 * @param savePath
	 *            文件下載到本地存儲的路徑,必須是目錄
	 * @param fileList
	 *            指定的要下載的文件名列表
	 * @throws SftpException
	 * @throws FileNotFoundException
	 */
	public static void downloadFileList(ChannelSftp sftp, String srcPath, String savePath, List<String> fileList)
			throws SftpException, FileNotFoundException {
		sftp.cd(srcPath);
		for (String srcFile : fileList) {
			logger.info("srcFile: " + srcFile);
			String localPath = savePath + SystemUtils.FILE_SEPARATOR + srcFile;
			sftp.get(srcFile, localPath);
		}
	}

	/**
	 * sftp下載目標服務器上所有指定的文件, 并解析文件的內容.<br/>
	 * 若本地存儲路徑下存在與下載重名的文件, 則忽略(不下載)該文件.<br/>
	 * 
	 * @param sftp
	 * @param srcPath
	 *            sftp上源文件的目錄
	 * @param savePath
	 *            文件下載到本地存儲的路徑,必須是目錄
	 * @param fileList
	 *            指定的要下載的文件列表
	 * @throws FileNotFoundException
	 * @throws SftpException
	 */
	private static void parseAndUpdateDB(ChannelSftp sftp, String srcPath, String savePath, List<String> fileList)
			throws FileNotFoundException, SftpException {
		sftp.cd(srcPath);
		for (String srcFile : fileList) {
			String localPath = savePath + SystemUtils.FILE_SEPARATOR + srcFile;
			File localFile = new File(localPath);
			// savePath路徑下已有文件與下載文件重名, 忽略這個文件
			if (localFile.exists() && localFile.isFile()) {
				continue;
			}

			logger.info("start downloading file: [" + srcFile + "], parseAndUpdate to DB");
			sftp.get(srcFile, localPath);
			//updateDB(localFile);
		}
	}

	/**
	 * 獲取srcPath路徑下以regex格式指定的文件列表
	 * 
	 * @param sftp
	 * @param srcPath
	 *            sftp服務器上的目錄
	 * @param regex
	 *            需要匹配的文件名
	 * @return
	 * @throws SftpException
	 */
	@SuppressWarnings("unchecked")
	public static List<String> listFiles(ChannelSftp sftp, String srcPath, String regex) throws SftpException {
		List<String> fileList = new ArrayList<String>();
		sftp.cd(srcPath); // 如果srcPath不是目錄則會拋出異常
		if ("".equals(regex) || regex == null) {
			regex = "*";
		}
		Vector<LsEntry> sftpFile = sftp.ls(regex);
		String fileName = null;
		for (LsEntry lsEntry : sftpFile) {
			fileName = lsEntry.getFilename();
			fileList.add(fileName);
		}
		return fileList;
	}

	/**
	 * 刪除文件
	 * 
	 * @param dirPath
	 *            要刪除文件所在目錄
	 * @param file
	 *            要刪除的文件
	 * @param sftp
	 * @throws SftpException
	 */
	public static void delete(String dirPath, String file, ChannelSftp sftp) throws SftpException {
		String now = sftp.pwd();
		sftp.cd(dirPath);
		sftp.rm(file);
		sftp.cd(now);
	}

	/**
	 * Disconnect with server
	 */
	public static void disconnect(ChannelSftp sftp) {
		try {
			if (sftp != null) {
				if (sftp.isConnected()) {
					sftp.disconnect();
				} else if (sftp.isClosed()) {
					logger.info("sftp is closed already");
				}
				if (null != sftp.getSession()) {
					sftp.getSession().disconnect();
				}
			}
		} catch (JSchException e) {
			// Ignore
		}

	}

	private static Session createSession(JSch jsch, String host, String username, int port) throws Exception {
		Session session = null;
		if (port <= 0) {
			// 連接服務器,采用默認端口
			session = jsch.getSession(username, host);
		} else {
			// 采用指定的端口連接服務器
			session = jsch.getSession(username, host, port);
		}
		// 如果服務器連接不上,則拋出異常
		if (session == null) {
			throw new Exception(host + "session is null");
		}
		// 設置第一次登陸的時候提示,可選值:(ask | yes | no)
		session.setConfig("StrictHostKeyChecking", "no");
		return session;
	}

	public static void main(String[] args) throws Exception {
	}
}
最近下載更多
阿昌先生 LV101月9日
月亮月亮星星星星
syh12355 LV52019年11月22日
月亮星星
godlike123 LV122019年10月17日
月亮月亮月亮
lelelada LV62019年8月9日
月亮星星星星
wisdomwang LV12019年6月14日
星星
han108 LV162019年3月6日
太陽
wsupsup LV132019年1月9日
月亮月亮月亮星星
zhangguobin LV122019年1月8日
月亮月亮月亮
813170344 LV32018年7月16日
星星星星星星
tankai998 LV122018年6月4日
月亮月亮月亮
最近瀏覽更多
小仙女本仙haha LV76月20日
月亮星星星星星星
yj541995 LV96月18日
月亮月亮星星
CoderMars LV126月8日
月亮月亮月亮
953821080 LV35月18日
星星星星星星
xingbing LV45月5日
月亮
幸運瘋子 LV114月28日
月亮月亮星星星星星星
Rommel LV234月22日
太陽月亮星星星星星星
13543318166 LV13月25日
星星
阿昌先生 LV101月9日
月亮月亮星星星星
wave小于 LV51月9日
月亮星星
頂部客服微信二維碼底部
>掃描二維碼關注最代碼為好友掃描二維碼關注最代碼為好友
黑龙江11选5实时走势图