文件传输在开发中还是经常会遇到的,通常情况会采用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