SFTP连接工具类

连接SFTP服务器使用的是jsch
用到以下几个jar包
commons-vfs-1.0.jar
commons-logging-1.1.1.jar
jsch-0.1.45.jar
也可以在远程机器上创建指定目录

下载文件到本地并指定文件名

package com.wxcking.admins.util.sftp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystemOptions;
import org.apache.commons.vfs.provider.sftp.SftpClientFactory;
import org.apache.commons.vfs.provider.sftp.SftpFileSystemConfigBuilder;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

/**
 * SFTP工具类
 */
public class SFTPUtil {
	private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger.getLogger(SFTPUtil.class);

	private ChannelSftp channel;

	private Session session;

	/** sftp用户名 */
	private String userName;
	/** sftp密码 */
	private String password;
	/** sftp主机ip */
	private String ftpHost;
	/** sftp主机端口 */
	private int ftpPort;

	/**
	 * 默认构造方法
	 */
	public SFTPUtil() {
	}

	/**
	 * 连接SFTP服务器
	 * 
	 * @param userName
	 * @param password
	 * @param ftpHost
	 * @param ftpPort
	 * @throws JSchException
	 * @throws FileSystemException
	 */
	public SFTPUtil(String userName, String password, String ftpHost,
			int ftpPort) throws JSchException, FileSystemException {
		this.userName = userName;
		this.password = password;
		this.ftpHost = ftpHost;
		this.ftpPort = ftpPort;
		
		LOGGER.info("SFTP连接信息: " + "userName=" + userName + ", " + "password="
				+ password + ", " + "ftpHost=" + ftpHost + ", " + "ftpPort=" + ftpPort);
		
		connectServer();
	}

	/**
	 * 从SFTP上下载文件到本地
	 * 
	 * @param sftp
	 *            sftp工具类
	 * @param remotePath
	 *            远程服务器文件路径
	 * @param remoteFile
	 *            sftp服务器文件名
	 * @param localFile
	 *            下载到本地的文件路径和名称
	 * @param localFile
	 *            true 表示关闭连接 false 表示不关闭连接
	 * @return flag 下载是否成功, true-下载成功, false-下载失败
	 * @throws Exception
	 */
	public boolean downFile(SFTPUtil sftp, String remotePath,
			String remoteFile, String localFile, boolean closeFlag) throws Exception {
		boolean flag = false;
		try {
			this.channel.cd(remotePath);
			InputStream input = this.channel.get(remoteFile);

			// 判断本地目录是否存在, 若不存在就创建文件夹
			if (localFile != null && !"".equals(localFile)) {
				File checkFileTemp = new File(localFile);
				if (!checkFileTemp.getParentFile().exists()) {
					// 创建文件夹, 如:在f盘创建/TXT文件夹/testTXT/两个文件夹 
					checkFileTemp.getParentFile().mkdirs();
				}
			}

			FileOutputStream out = new FileOutputStream(new File(localFile));
			byte[] bt = new byte[1024];
			int length = -1;
			while ((length = input.read(bt)) != -1) {
				out.write(bt, 0, length);
			}
			input.close();
			out.close();
			if (closeFlag) {
				sftp.disconnect();
			}
			flag = true;
		} catch (SftpException e) {
			LOGGER.error("文件下载失败!", e);
			throw new RuntimeException("文件下载失败!");
		} catch (FileNotFoundException e) {
			LOGGER.error("下载文件到本地的路径有误!", e);
			throw new RuntimeException("下载文件到本地的路径有误!");
		} catch (IOException e) {
			LOGGER.error("文件写入有误!", e);
			throw new RuntimeException("文件写入有误!");
		}

		return flag;
	}

	/**
	 * 下载文件
	 * 
	 * @param sftp
	 * @param remotePath
	 *            远程文件路径
	 * @param remoteFileName
	 *            远程文件名称
	 * @param localFilePath
	 *            本地文件路径
	 * @param localFileName
	 *            本地文件名称
	 * @param closeFlag
	 *            是否关闭SFTP连接true-关闭连接, false-不关闭连接
	 * @return 下载是否成功, true-下载成功, false-下载失败
	 * @throws Exception
	 */
	public boolean downFile(SFTPUtil sftp, String remotePath, String remoteFileName, 
			String localFilePath, String localFileName, boolean closeFlag) throws Exception {
		boolean flag = false;
		try {
			this.channel.cd(remotePath);
			InputStream input = this.channel.get(remoteFileName);
			String localRemoteFile = localFilePath + remoteFileName;
			File checkFileTemp = null;
			// 判断本地目录是否存在, 若不存在就创建文件夹
			if (localRemoteFile != null && !"".equals(localRemoteFile)) {
				checkFileTemp = new File(localRemoteFile);
				if (!checkFileTemp.getParentFile().exists()) {
					// 创建文件夹, 如:在f盘创建/TXT文件夹/testTXT/两个文件夹
					checkFileTemp.getParentFile().mkdirs();
				}
			}

			FileOutputStream out = new FileOutputStream(new File(localRemoteFile));
			byte[] bt = new byte[1024];
			int length = -1;
			while ((length = input.read(bt)) != -1) {
				out.write(bt, 0, length);
			}
			input.close();
			out.close();
			if (closeFlag) {
				sftp.disconnect();
			}
			flag = true;

			// 下载后的文件重命名
			File upSupFile = new File(localFilePath + localFileName);
			checkFileTemp.renameTo(upSupFile);
		} catch (SftpException e) {
			LOGGER.error("文件下载失败!", e);
			throw new RuntimeException("文件下载失败!");
		} catch (FileNotFoundException e) {
			LOGGER.error("下载文件到本地的路径有误!", e);
			throw new RuntimeException("下载文件到本地的路径有误!");
		} catch (IOException e) {
			LOGGER.error("文件写入有误!", e);
			throw new RuntimeException("文件写入有误!");
		}

		return flag;
	}
	
	/**
	 * 上传文件到SFTP服务器
	 * 
	 * @param remotePath
	 *            sftp服务器路径
	 * @param fileName
	 *            sftp服务器文件名
	 * @param localFile
	 *            本地文件路径和名称字符串
	 * @param closeFlag
	 *            是否要关闭本次SFTP连接: true-关闭, false-不关闭
	 * @param filePathFlag
	 *            是否要创建远程的指定目录: true-创建, false-不创建
	 * @throws IOException
	 */
	public boolean upFile(String remotePath, String fileName, String localFile,
			boolean closeFlag, boolean filePathFlag) throws Exception {
		boolean flag = false;
		InputStream input = null;
		try {
			input = new FileInputStream(localFile);

			// 判断是否要在远程目录上创建对应的目录
			if (filePathFlag) {
				String[] dirs = remotePath.split("\\/");
				if (dirs == null || dirs.length < 1) {
					dirs = remotePath.split("\\\\");
				}

				String now = this.channel.pwd();
				for (int i = 0; i < dirs.length; i++) {
					if (dirs[i] != null && !"".equals(dirs[i])) {
						boolean dirExists = this.openDirs(dirs[i]);
						if (!dirExists) {
							this.channel.mkdir(dirs[i]);
							this.channel.cd(dirs[i]);
						}
					}
				}
				this.channel.cd(now);
			}
			
			this.channel.cd(remotePath);
			this.channel.put(input, fileName);
			
			flag = true;
		} catch (SftpException e) {
			LOGGER.error("文件上传失败!", e);
			throw new RuntimeException("文件上传失败!");
		} catch (FileNotFoundException e) {
			LOGGER.error("FileNotFoundException 上传文件找不到!", e);
			throw new RuntimeException("上传文件路径有误!");
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (Exception localException1) {
					LOGGER.error("输入流关闭失败", localException1);
				}
			}
			// 判断是否要关闭本次SFTP连接
			if (closeFlag) {
				disconnect();
			}
		}
		
		return flag;
	}

	/**
	 * 连接SFTP服务器
	 * 
	 * @throws JSchException
	 * @throws FileSystemException
	 */
	private void connectServer() throws JSchException, FileSystemException {
		if (this.channel != null) {
			disconnect();
		}
		
		com.jcraft.jsch.Logger logger = new SettleLogger();
        JSch.setLogger(logger);
		
		FileSystemOptions fso = new FileSystemOptions();
		SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(fso, "no");
		
		LOGGER.info("SFTP连接正在创建Session... ...");
		this.session = SftpClientFactory.createConnection(this.ftpHost,
				this.ftpPort, this.userName.toCharArray(),
				this.password.toCharArray(), fso);
		LOGGER.info("SFTP连接Session创建成功");
		
		LOGGER.info("SFTP连接正在打开SFTP通道... ...");
		Channel _channel = this.session.openChannel("sftp");
		LOGGER.info("SFTP连接通道打开成功");
		
		LOGGER.info("SFTP连接中... ...");
		_channel.connect();
		LOGGER.info("SFTP连接成功");
		
		this.channel = ((ChannelSftp) _channel);
	}

	/**
	 * 关闭连接
	 */
	private void disconnect() {
		if (this.channel != null) {
			this.channel.exit();
		}
		if (this.session != null) {
			this.session.disconnect();
		}
		this.channel = null;
	}

	/**
	 * 下载文件
	 * 
	 * @param remotePath
	 * @param remoteFile
	 * @return
	 * @throws Exception 
	 */
	public InputStream downFile(String remotePath, String remoteFile) throws Exception {
		try {
			this.channel.cd(remotePath);
			return this.channel.get(remoteFile);
		} catch (SftpException e) {
			LOGGER.error("文件下载失败!", e);
			throw new Exception("文件下载失败", e);
		}
	}

	/**
	 * 打开指定目录
	 * 
	 * @param sftp
	 *            ChannelSftp
	 * @param directory
	 *            directory
	 * @return 是否打开目录
	 */
	public boolean openDirs(String directory) {
		try {
			this.channel.cd(directory);
			return true;
		} catch (SftpException e) {
			return false;
		}
	}

}


你可能感兴趣的:(sftp)