文件传输在开发中还是经常会遇到的,通常情况会采用ftp协议,java实现ftp协议传输的工具还是有挺多的选择的,比如apache的commons-net工具包。要想程序实现sftp协议或ssh协议的传输文件,也是很容易的,这时用到的就是jcraft的Jsch工具包了。
如果项目采用maven构建的话,引入
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.50</version> </dependency>
使用的情况:服务器是linux系统,我们需要将我们的文件上传到指定的目录下,使用ssh2协议或sftp协议。
代码示列:
import java.util.Properties; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.SftpException; /** * @ClassName: JschSFTP * @Description: sftp文件传输工具类 * @author lipenglong * @date 2013-12-13 下午4:50 */ public class JschSFTP { private Session session = null; private Channel channel = null; private String sftpHost; private int sftpPort; private String sftpUserName; private String sftpPassword; private int timeout; public void setSftpHost(String sftpHost) { this.sftpHost = sftpHost; } public void setSftpPort(int sftpPort) { this.sftpPort = sftpPort; } public void setSftpUserName(String sftpUserName) { this.sftpUserName = sftpUserName; } public void setSftpPassword(String sftpPassword) { this.sftpPassword = sftpPassword; } public void setTimeout(int timeout) { this.timeout = timeout; } /** * 获取连接 * @return */ private ChannelSftp getChannelSftp() { try { if (channel != null && channel.isConnected()) { return (ChannelSftp) channel; } JSch jSch = new JSch(); if (session == null || !session.isConnected()) { session = jSch.getSession(sftpUserName, sftpHost, sftpPort); session.setPassword(sftpPassword); Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.setTimeout(timeout); session.connect(); } channel = session.openChannel("sftp"); channel.connect(); } catch (Exception e) { Log4jUtil.CommonLog.error(e.getMessage(), e); if (session != null) { session.disconnect(); session = null; } channel = null; } return channel == null ? null : (ChannelSftp) channel; } /** * 关闭连接 */ public void closeChannel() { try { if (channel != null) { channel.disconnect(); channel = null; } if (session != null) { session.disconnect(); session = null; } } catch (Exception e) { Log4jUtil.CommonLog.error(e.getMessage(), e); } } /** * 文件上传 * @param src 源文件absolutePath * @param dst 目标文件名 * @param dir 目标文件路径 * @return boolean */ public boolean uploadFile(String src, String dst, String dir) { boolean flag = false; ChannelSftp channelSftp = getChannelSftp(); if (channelSftp == null) { return false; } try { channelSftp.cd(dir); channelSftp.put(src, dst, ChannelSftp.OVERWRITE); flag = true; } catch (Exception e) { flag = false; Log4jUtil.CommonLog.error(e.getMessage(), e); } return flag; } /** * 重命名 * @param oldName 旧文件名 * @param newName 新文件名 * @param dir 文件所在路径 * @return boolean */ public boolean renameTmpFile(String oldName, String newName, String dir) { boolean flag = false; ChannelSftp channelSftp = getChannelSftp(); if (channelSftp == null) { return false; } try { channelSftp.cd(dir); channelSftp.rename(oldName, newName); flag = true; } catch (SftpException e) { flag = false; Log4jUtil.CommonLog.error(e.getMessage(), e); try { channelSftp.rm(newName); } catch (SftpException e1) { } } return flag; } }
我曾写过的一个程序情况:把一个数据包**.rar上传到服务器(如/var/data/),文件大小不一定,上传中文件为"/var/data/**.rar.tmp"上传成功后去掉“.tmp",这两个方法就可以实现了~
配置参数可通过spring的注入,例如
sftpHost:192.168.1.**
sftpPort:22
sftpUserName:root(当然通常不会用root用户的)
sftpPassword:***(只有自己知道了~)
timeout:30000