JAVA使用jcraft操作SFTP工具类

jcraft包下载:https://download.csdn.net/download/ruixue0117/10922182

工具类用途针对Linux搭建文件服务器,上传和下载都使用文件流方式(使用Resquest和Response)。

功能包括:上传下载,批量上传下载,文件流上传(Request),下载写入文件流(Response),直接读取文件内容,直接写入文件,目录操作,文件删除。

SFtpUtils.java

package hh.com.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Vector;

import javax.servlet.http.HttpServletResponse;

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

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.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;

import hh.com.exception.CustomException;

/**
 * SFTP工具类
 * 
 * @author xxx
 * @date 2019-1-17
 * @version 1.0
 */
public class SFtpUtils {

	private static Log logger = LogFactory.getLog(SFtpUtils.class);

	// FTP名称
	private String ftpName;
	// FTP 登录用户名
	private String username;
	// FTP 登录密码
	private String password;
	// FTP 服务器地址IP地址
	private String host;
	// FTP 端口
	private int port;
	// 属性集
	private ResourceBundle property = null;
	// 配置文件的路径名
	private String configFile = "ftpconfig";
	// 编码格式
	private String encoding = "utf-8";
	// 根目录
	private String homeDir = "/ftp/fs01/";
	
	private ChannelSftp sftp = null;
	private Session sshSession = null;
	
	public SFtpUtils(String ftpName) {
		this.ftpName = ftpName;
		setArg(configFile);
	}

	public static void main(String[] args) {
		SFtpUtils sftp = null;
		// 本地存放地址
		String localPath = "E:\\logs\\";
		// Sftp下载路径
		String sftpPath = "/SFTP_FILES/TEST/";
		try {
			sftp = new SFtpUtils("ATTACHMENT_");
			sftp.uploadFile(new FileInputStream(new File(localPath + "logs.txt")), "logs.txt", sftpPath);
			sftp.downFile("/SFTP_FILES/TEST/", "logs.txt", "E:\\logs\\", "logs2.txt");
			sftp.writeToFtp("/SFTP_FILES/TEST/logs1.txt", "有新的特殊订单待处理。");
			StringBuffer sb = sftp.readFile("/SFTP_FILES/TEST/logs1.txt");
			System.out.println(sb.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 设置参数
	 * @param configFile 参数的配置文件
	 */
	private void setArg(String configFile) {
		try {
			property = ResourceBundle.getBundle(configFile);
			username = property.getString(ftpName+"username");
			password = property.getString(ftpName+"password");
			host = property.getString(ftpName+"host");
			port = Integer.parseInt(property.getString(ftpName+"port"));
		} catch (Exception e) {
			System.out.println("配置文件 " + configFile + " 无法读取!");
		}
	}

	/**
	 * 通过SFTP连接服务器
	 */
	private void connect() {
		try {
			JSch jsch = new JSch();
			jsch.getSession(username, host, port);
			sshSession = jsch.getSession(username, host, port);
			if (logger.isInfoEnabled()) {
				logger.info("Session created.");
			}
			sshSession.setPassword(password);
			Properties sshConfig = new Properties();
			sshConfig.put("StrictHostKeyChecking", "no");
			sshSession.setConfig(sshConfig);
			sshSession.connect();
			if (logger.isInfoEnabled()) {
				logger.info("Session connected.");
			}
			Channel channel = sshSession.openChannel("sftp");
			channel.connect();
			if (logger.isInfoEnabled()) {
				logger.info("Opening Channel.");
			}
			sftp = (ChannelSftp) channel;
			if (logger.isInfoEnabled()) {
				logger.info("Connected to " + host + ".");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 关闭连接
	 */
	private void disconnect() {
		if (this.sftp != null) {
			if (this.sftp.isConnected()) {
				this.sftp.disconnect();
				if (logger.isInfoEnabled()) {
					logger.info("sftp is closed already");
				}
			}
		}
		if (this.sshSession != null) {
			if (this.sshSession.isConnected()) {
				this.sshSession.disconnect();
				if (logger.isInfoEnabled()) {
					logger.info("sshSession is closed already");
				}
			}
		}
	}

	/**
	 * 批量下载文件
	 * 
	 * @param remotPath:远程下载目录(以路径符号结束,可以为相对路径eg:/assess/sftp/jiesuan_2/2014/)
	 * @param localPath:本地保存目录(以路径符号结束,D:\Duansha\sftp\)
	 * @param fileFormat:下载文件格式(以特定字符开头,为空不做检验)
	 * @param fileEndFormat:下载文件格式(文件格式)
	 * @param del:下载后是否删除sftp文件
	 * @return
	 */
	public List<String> batchDownFile(String remotePath, String localPath, String fileFormat, String fileEndFormat, boolean del) {
		List<String> filenames = new ArrayList<String>();
		boolean _flag = false;
		try {
			if (!isConnect()){
				connect();
				_flag = true;
			}
			Vector v = listFiles(remotePath);
			if (v.size() > 0) {
				Iterator it = v.iterator();
				while (it.hasNext()) {
					LsEntry entry = (LsEntry) it.next();
					String filename = entry.getFilename();
					SftpATTRS attrs = entry.getAttrs();
					if (!attrs.isDir()) {
						boolean flag = false;
						String localFileName = localPath + filename;
						fileFormat = fileFormat == null ? "" : fileFormat.trim();
						fileEndFormat = fileEndFormat == null ? "" : fileEndFormat.trim();
						// 三种情况
						if (fileFormat.length() > 0 && fileEndFormat.length() > 0) {
							if (filename.startsWith(fileFormat) && filename.endsWith(fileEndFormat)) {
								flag = downFile(remotePath, filename, localPath, filename);
								if (flag) {
									filenames.add(localFileName);
									if (flag && del) {
										deleteSFTP(remotePath, filename);
									}
								}
							}
						} else if (fileFormat.length() > 0 && "".equals(fileEndFormat)) {
							if (filename.startsWith(fileFormat)) {
								flag = downFile(remotePath, filename, localPath, filename);
								if (flag) {
									filenames.add(localFileName);
									if (flag && del) {
										deleteSFTP(remotePath, filename);
									}
								}
							}
						} else if (fileEndFormat.length() > 0 && "".equals(fileFormat)) {
							if (filename.endsWith(fileEndFormat)) {
								flag = downFile(remotePath, filename, localPath, filename);
								if (flag) {
									filenames.add(localFileName);
									if (flag && del) {
										deleteSFTP(remotePath, filename);
									}
								}
							}
						} else {
							flag = downFile(remotePath, filename, localPath, filename);
							if (flag) {
								filenames.add(localFileName);
								if (flag && del) {
									deleteSFTP(remotePath, filename);
								}
							}
						}
					}
				}
			}
			if (logger.isInfoEnabled()) {
				logger.info("download file is success:remotePath=" + remotePath + "and localPath=" + localPath + ",file size is" + v.size());
			}
		} catch (SftpException e) {
			e.printStackTrace();
		} finally {
			if (_flag)
				disconnect();
		}
		return filenames;
	}

	/**
	 * 下载单个文件
	 * 
	 * @param remotPath:远程下载目录(以路径符号结束)
	 * @param remoteFileName:下载文件名
	 * @param localPath:本地保存目录(以路径符号结束)
	 * @param localFileName:保存文件名
	 * @return
	 */
	public boolean downFile(String remotePath, String remoteFileName, String localPath, String localFileName) {
		FileOutputStream fieloutput = null;
		boolean _flag = false;
		try {
			if (!isConnect()){
				connect();
				_flag = true;
			}
			File file = new File(localPath + localFileName);
			fieloutput = new FileOutputStream(file);
			sftp.get(homeDir + remotePath + remoteFileName, fieloutput);
			if (logger.isInfoEnabled()) {
				logger.info("DownloadFile:" + remoteFileName + " success from sftp.");
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != fieloutput) {
				try {
					fieloutput.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (_flag)
				disconnect();
		}
		return false;
	}
	
	/**
	 * 下载单个文件
	 * 
	 * @param remotePath:远程下载目录
	 * @param remoteFileName:下载文件名
	 * @param response
	 * @return
	 */
	public boolean downFile(String remotePath, String newFileName, HttpServletResponse response) {
		OutputStream outputStream = null;
		boolean _flag = false;
		try {
			if (!isConnect()){
				connect();
				_flag = true;
			}
			// 输出文件流
			response.reset(); // 非常重要
			response.setContentType("application/x-msdownload");
			response.setHeader("Content-Disposition", "attachment; filename=" + new String(newFileName.getBytes("GBK"), "ISO-8859-1"));
			
			outputStream = response.getOutputStream();
			sftp.get(homeDir + remotePath, outputStream);
			outputStream.flush();
			outputStream.close();
			if (logger.isInfoEnabled()) {
				logger.info("DownloadFile:" + newFileName + " success from sftp.");
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != outputStream) {
				try {
					outputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (_flag)
				disconnect();
		}
		return false;
	}
	
	/**
	 * 读取文件
	 * @param remoteFileName
	 * @return
	 */
	public StringBuffer readFile(String remoteFileName) {
		StringBuffer resultBuffer = new StringBuffer();
		InputStream in = null;
		boolean _flag = false;
		try {
			if (!isConnect()) {
				connect();
				_flag = true;
			}
			
			in = sftp.get(homeDir + remoteFileName);
			if(in == null) return resultBuffer;
			
			BufferedReader br = new BufferedReader(new InputStreamReader(in, encoding));
			String data = null;
			try {
				while ((data = br.readLine()) != null) {
					resultBuffer.append(data + "\n");
				}
			} catch (IOException e) {
				logger.error("文件读取错误。");
				e.printStackTrace();
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.debug("本地文件下载失败!", e);
		} finally {
			try {
				if (in != null)
					in.close();
			} catch (Exception e) {
//				e.printStackTrace();
			}
			if (_flag)
				disconnect();
		}
		return resultBuffer;
	}
	
	/**
	 * 写入字符串到FTP文件
	 * @param path
	 * @param content
	 */
	public void writeToFtp(String path, String content) throws CustomException,Exception{
		boolean _flag = false;
		try {
			if (!isConnect()) {
				connect();
				_flag = true;
			}
			
			String remoteFileName = path.substring(path.lastIndexOf("/") + 1);
			String remotePath = path.substring(0, path.lastIndexOf("/") + 1);
			
			InputStream in = new ByteArrayInputStream(content.getBytes(encoding));
			uploadFile(in, remoteFileName, remotePath);
		} catch (Exception e) {
			e.printStackTrace();
			logger.debug("文件写入失败!", e);
			throw new CustomException(path + "写入失败!");
		} finally {
			if (_flag)
				disconnect();
		}
	}

	/**
	 * 上传单个文件
	 * 
	 * @param remotePath:远程保存目录
	 * @param remoteFileName:保存文件名
	 * @param localPath:本地上传目录(以路径符号结束)
	 * @param localFileName:上传的文件名
	 * @return
	 */
	public boolean uploadFile(InputStream in, String remoteFileName, String remotePath) {
		boolean _flag = false;
		try {
			if (!isConnect()){
				connect();
				_flag = true;
			}
			createDir(remotePath);
			sftp.put(in, remoteFileName);
			return true;
		} catch (SftpException e) {
			e.printStackTrace();
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (_flag)
				disconnect();
		}
		return false;
	}

	/**
	 * 批量上传文件
	 * 
	 * @param remotePath:远程保存目录
	 * @param localPath:本地上传目录(以路径符号结束)
	 * @param del:上传后是否删除本地文件
	 * @return
	 */
	public boolean bacthUploadFile(String remotePath, String localPath, boolean del) {
		boolean _flag = false;
		try {
			if (!isConnect()){
				connect();
				_flag = true;
			}
			File file = new File(localPath);
			File[] files = file.listFiles();
			for (int i = 0; i < files.length; i++) {
				if (files[i].isFile() && files[i].getName().indexOf("bak") == -1) {
					if (this.uploadFile(new FileInputStream(files[i]), files[i].getName(), remotePath) && del) {
						deleteFile(localPath + files[i].getName());
					}
				}
			}
			if (logger.isInfoEnabled()) {
				logger.info("upload file is success:remotePath=" + remotePath + "and localPath=" + localPath + ",file size is " + files.length);
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (_flag)
				this.disconnect();
		}
		return false;

	}

	/**
	 * 删除本地文件
	 * 
	 * @param filePath
	 * @return
	 */
	public boolean deleteFile(String filePath) {
		File file = new File(filePath);
		if (!file.exists()) {
			return false;
		}

		if (!file.isFile()) {
			return false;
		}
		boolean rs = file.delete();
		if (rs && logger.isInfoEnabled()) {
			logger.info("delete file success from local.");
		}
		return rs;
	}

	/**
	 * 创建目录
	 * 
	 * @param createpath
	 * @return
	 */
	public boolean createDir(String createpath) {
		boolean _flag = false;
		createpath = homeDir + createpath;
		try {
			if (!isConnect()){
				connect();
				_flag = true;
			}
			if (isDirExist(createpath)) {
				this.sftp.cd(createpath);
				return true;
			}
			String pathArry[] = createpath.split("/");
			StringBuffer filePath = new StringBuffer("/");
			for (String path : pathArry) {
				if (path.equals("")) {
					continue;
				}
				filePath.append(path + "/");
				if (isDirExist(filePath.toString())) {
					sftp.cd(filePath.toString());
				} else {
					// 建立目录
					sftp.mkdir(filePath.toString());
					// 进入并设置为当前目录
					sftp.cd(filePath.toString());
				}

			}
			this.sftp.cd(createpath);
			return true;
		} catch (SftpException e) {
			e.printStackTrace();
		} finally {
			if (_flag)
				disconnect();
		}
		return false;
	}

	/**
	 * 判断目录是否存在
	 * 
	 * @param directory
	 * @return
	 */
	public boolean isDirExist(String directory) {
		boolean isDirExistFlag = false;
		boolean _flag = false;
		try {
			if (!isConnect()){
				connect();
				_flag = true;
			}
			SftpATTRS sftpATTRS = sftp.lstat(directory);
			isDirExistFlag = true;
			return sftpATTRS.isDir();
		} catch (Exception e) {
			if (e.getMessage().toLowerCase().equals("no such file")) {
				isDirExistFlag = false;
			}
		} finally {
			if (_flag)
				disconnect();
		}
		return isDirExistFlag;
	}

	/**
	 * 删除stfp文件
	 * 
	 * @param directory:要删除文件所在目录
	 * @param deleteFile:要删除的文件
	 * @param sftp
	 */
	public void deleteSFTP(String directory, String deleteFile) {
		boolean _flag = false;
		try {
			if (!isConnect()){
				connect();
				_flag = true;
			}
			sftp.rm(homeDir + directory + deleteFile);
			if (logger.isInfoEnabled()) {
				logger.info("delete file success from sftp.");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (_flag)
				disconnect();
		}
	}

	/**
	 * 如果目录不存在就创建目录
	 * 
	 * @param path
	 */
	public void mkdirs(String path) {
		File f = new File(path);

		String fs = f.getParent();

		f = new File(fs);

		if (!f.exists()) {
			f.mkdirs();
		}
	}

	/**
	 * 列出目录下的文件
	 * 
	 * @param directory:要列出的目录
	 * @param sftp
	 * @return
	 * @throws SftpException
	 */
	public Vector listFiles(String directory) throws SftpException {
		boolean _flag = false;
		if (!isConnect()){
			connect();
			_flag = true;
		}
		Vector ls = sftp.ls(homeDir + directory);
		if (_flag)
			disconnect();
		return ls;
	}
	
	public boolean isConnect() {
		return (this.sftp != null && this.sftp.isConnected() && this.sshSession != null && this.sshSession.isConnected());
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public ChannelSftp getSftp() {
		return sftp;
	}

	public void setSftp(ChannelSftp sftp) {
		this.sftp = sftp;
	}
}

ftpconfig.properties

#FTP配置文件
#============Attachment============#
ATTACHMENT_username=sftp_hrdms
ATTACHMENT_password=sftp_hrdms2019
ATTACHMENT_host=192.168.1.203
ATTACHMENT_port=22

ATTATEST_username=root
ATTATEST_password=123123123
ATTATEST_host=120.79.79.189
ATTATEST_port=22

 

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值