一、实例代码
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), 默认端口号是22session = 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对象 |