一、实例代码
package com.summer.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import org.apache.log4j.Logger;
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通道实现文件的上传与下载
*
* @author Administrator
*
*/
public class SFTPUtil {
private Logger log = Logger.getLogger(SFTPUtil.class);
private static Session session;
private static Channel channel;
private static ChannelSftp sftp;
/**
* 创建SFTP通道
*
* @param username
* 访问SFTP服务器的用户名
* @param host
* SFTP服务器的IP
* @param port
* SFTP服务器的端口号
* @param password
* 访问SFTP服务器的密码
* @param timeOut
* 访问SFTP服务器超时时间,单位:毫秒
*/
public ChannelSftp getSFTPConnection(String username, String host,
int port, String password, int timeOut) {
try {
JSch jsch = new JSch();
// 参数为sftp服务器的IP、PORT、USERNAME、PASSWORD
// getSession(String username, String host, int port), 默认端口号是22
session = jsch.getSession(username, host, port);
session.setPassword(password);
Properties config = new Properties();
// Jsch优先使用RSA key type密钥的方式登陆
// 此处使用用户名和密码方式登录
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
// 设置访问超时时间
session.connect(timeOut);
log.info("连接会话开启成功!");
// 创建sftp通信通道
channel = session.openChannel("sftp");
channel.connect();
log.info("SFTP连接成功");
sftp = (ChannelSftp) channel;
// sftp.quit();
} catch (JSchException e) {
log.error("创建sftp通道失败");
log.error(e.getMessage());
} finally {
// sftp通道需返回给调用者,所以fianlly中不能关闭,需在调用后关闭
/*
* if (sftp != null) sftp.disconnect(); if (channel != null)
* channel.disconnect(); if (session != null) session.disconnect();
*/
}
return sftp;
}
/**
* 使用SFTP通道上传文件
*
* @param sftp
* @param sourceFile
* 要上传的源文件
* @param destFile
* 目标文件
* @return 上传成功返回true,失败返回false
*/
public boolean fileUpload(ChannelSftp sftp, String sourceFile,
String destFile) {
OutputStream outstream = null;
InputStream instream = null;
try {
// 以下代码实现从本地上传一个文件到服务器/usr/uploadFileName.txt文件,如果要实现下载,对换以下流就可以了
outstream = sftp.put(destFile);
instream = new FileInputStream(new File(sourceFile));
byte b[] = new byte[1024];
int n;
while ((n = instream.read(b)) != -1) {
outstream.write(b, 0, n);
}
outstream.flush();
log.info("文件上传成功");
return true;
// sftp.disconnect();
// sftp.quit();
} catch (IOException e) {
log.error("文件上传失败");
log.error(e.getMessage());
return false;
} catch (SftpException e) {
log.error("文件上传失败");
log.error(e.getMessage());
return false;
} finally {
try {
if (instream != null)
instream.close();
if (outstream != null)
outstream.close();
if (sftp != null)
sftp.disconnect();
} catch (IOException e) {
log.error("关闭流失败");
log.error(e.getMessage());
}
}
}
/**
* 断开连接,关闭资源
*/
public void close() {
if (sftp != null)
sftp.disconnect();
if (channel != null)
channel.disconnect();
if (session != null)
session.disconnect();
}
/**
* 测试
* @param args
*/
public static void main(String[] args) {
SFTPUtil util = new SFTPUtil();
ChannelSftp sftp = util.getSFTPConnection("root", "192.168.11.1", 22,
"root", 30000);
util.fileUpload(sftp, "C:/svn=.txt", "/usr/test.txt");
util.close();
}
}
二、JSch实现SFTP功能一些主要类的介绍
1)JSch 类
2)Session 会话对象类
3)
ChannelSFTP类
ChannelSFTP类是JSch实现SFTP核心类,它提供了一些SFTP常见的操作方法,如下
方法名 | 方法说明 |
put() | 文件上传 |
get() | 文件下载 |
cd()
| 进入指定目录 |
ls()
| 得到指定目录下的文件列表 |
rename()
| 重命名(移动)指定文件或目录 |
rm()
| 删除指定文件 |
mkdir()
| 创建目录 |
rmdir()
| 删除目录(只允许删除空目录) |
注:以上这些方法都有很多重载方法
4)
SftpProgressMonitor 传输进度监控类
5)
LsEntry 可以认为是文件服务器上的文件条目信息,把包含文件或者目录相关属性 。ls命令返回的Vector中的就是LsEntry对象列表
三、ChannelSftp类的主要API说明如下:
方法名 | 方法说明 |
public void put(String src, String dst) | 将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同。采用默认的传输模式:OVERWRITE |
public void put(String src, String dst, int mode) | 将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同。指定文件传输模式为mode(mode可选值为:ChannelSftp.OVERWRITE,ChannelSftp.RESUME,ChannelSftp.APPEND)。 |
public void put(String src, String dst, SftpProgressMonitor monitor) | 将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同。采用默认的传输模式:OVERWRITE,并使用实现了SftpProgressMonitor接口的monitor对象来监控文件传输的进度。 |
public void put(String src, String dst,SftpProgressMonitor monitor, int mode) | 将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同。指定传输模式为mode,并使用实现了SftpProgressMonitor接口的monitor对象来监控文件传输的进度。 |
public void put(InputStream src, String dst) | 将本地的input stream对象src上传到目标服务器,目标文件名为dst,dst不能为目录。采用默认的传输模式:OVERWRITE |
public void put(InputStream src, String dst, int mode) | 将本地的input stream对象src上传到目标服务器,目标文件名为dst,dst不能为目录。指定文件传输模式为mode |
public void put(InputStream src, String dst, SftpProgressMonitor monitor) | 将本地的input stream对象src上传到目标服务器,目标文件名为dst,dst不能为目录。采用默认的传输模式:OVERWRITE。并使用实现了SftpProgressMonitor接口的monitor对象来监控传输的进度。 |
public void put(InputStream src, String dst,SftpProgressMonitor monitor, int mode) | 将本地的input stream对象src上传到目标服务器,目标文件名为dst,dst不能为目录。指定文件传输模式为mode。并使用实现了SftpProgressMonitor接口的monitor对象来监控传输的进度。 |
public OutputStream put(String dst) | 该方法返回一个输出流,可以向该输出流中写入数据,最终将数据传输到目标服务器,目标文件名为dst,dst不能为目录。采用默认的传输模式:OVERWRITE |
public OutputStream put(String dst, final int mode) | 该方法返回一个输出流,可以向该输出流中写入数据,最终将数据传输到目标服务器,目标文件名为dst,dst不能为目录。指定文件传输模式为mode |
public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode) | 该方法返回一个输出流,可以向该输出流中写入数据,最终将数据传输到目标服务器,目标文件名为dst,dst不能为目录。指定文件传输模式为mode。并使用实现了SftpProgressMonitor接口的monitor对象来监控传输的进度。 |
public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode, long offset) | 该方法返回一个输出流,可以向该输出流中写入数据,最终将数据传输到目标服务器,目标文件名为dst,dst不能为目录。指定文件传输模式为mode。并使用实现了SftpProgressMonitor接口的monitor对象来监控传输的进度。offset指定了一个偏移量,从输出流偏移offset开始写入数据。 |
get(String src, String dst) | 下载文件到本地,src为目标服务器上的文件,不能为目录,dst为本地文件路径。若dst为目录,则本地文件名与目标服务器上的文件名一样。 |
get(String src, String dst ,SftpProgressMonitor monitor) | 同get(String src, String dst),只是该方法允许传入传输进度的监控对象monitor。 |
get(String src, String dst ,SftpProgressMonitor monitor ,int mode) | 同get(String src, String dst ,SftpProgressMonitor monitor),同时,该方法增加了mode参数,允许指定文件传输模式 |
rm(String path) | 删除文件,path不能为目录,删除目录使用rmdir |
rmdir(String path) | 删除目录,但是只能删除空目录 |
rename(String oldpath, String newpath) | 如果oldPath为目录,不要求目录必须为空 如果newpath为目录,则newpath必须不能存在,如果已经存在该目录,则会出现重名或者移动失败 1、重命名文件或者目录 2、移动文件或者目录 |
ls(String path) | 列出指定目录下的所有文件和子目录。该方法返回Vector对象,该列表具体存放的是LsEntry对象 |