SFTP
SFTP是Secure File Transfer Protocol的缩写,安全文件传送协议。SFTP为SSH的一部份,是一种传输文件到服务器的安全加密的方式。
JSch
JSch是ssh的Java实现,从官网http://www.jcraft.com/jsch/ 下载jar包(jsch-0.1.55.jar),加入项目即可。
使用JSch连接SFTP
使用JSch连接SFTP服务器操作的步骤大致为:
- 使用ip、port、username、password等信息连接sftp,获取Session
- Session可以设置一系列属性,如超时时间等,通过Session建立链接
- Session建立连接后,打开SFTP通道Channel
- Channel连接之后便形成可用的ChannelSftp
- JSch封装了常用指令,如:sftp.put()、sftp.cd()、sftp.get()、sftp.ls(),可以进行操作
- 操作完成后,要关闭通道Channel和Session。
源码
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.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Vector;
/**
* SFTP Utils
*
*/
public class SFTPUtils {
private static final Logger logger = LoggerFactory.getLogger(SFTPUtils.class);
private static int TIMEOUT = 60000; // 超时数为一分钟,默认是0,表示没有超时数,单位毫秒
private ChannelSftp sftp;
public static SFTPUtils getInstance(String host, int port, String username, String password) {
SFTPUtils instance = new SFTPUtils(host, port, username, password);
return instance;
}
private SFTPUtils(String host, int port, String username, String password) {
sftp = connect(host, port, username, password); // 获取连接
}
/**
* 连接sftp服务器,创建一个sftp通道对象,通过这 个对象可以直接发送文件。
*
* @param host
* 主机
* @param port
* 端口
* @param username
* 用户名
* @param password
* 密码
* @return
*/
public ChannelSftp connect(String host, int port, String username, String password) {
ChannelSftp sftp = null;
try {
JSch jsch = new JSch();
Session sshSession = jsch.getSession(username, host, port);
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig); // 为Session对象设置properties
sshSession.setTimeout(TIMEOUT); // 设置timeout时间
sshSession.connect(); // 通过Session建立链接
logger.info("SFTP Session connected.");
Channel channel = sshSession.openChannel("sftp"); // 打开SFTP通道
channel.connect(); // 建立SFTP通道的连接
sftp = (ChannelSftp) channel;
logger.info("Connected to " + host);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return sftp;
}
/**
* 上传文件
*
* @param directory
* 上传的目录
* @param uploadFile
* 要上传的文件全路径
*/
public boolean upload(String targetDirectory, String uploadFile) {
try {
Vector dir = sftp.ls(targetDirectory);
if (dir == null) { // 如果路径不存在,则创建
sftp.mkdir(targetDirectory);
}
sftp.cd(targetDirectory);
File file = new File(uploadFile);
FileInputStream fileInputStream = new FileInputStream(file);
sftp.put(fileInputStream, file.getName());
fileInputStream.close();
return true;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return false;
}
}
/**
* 下载文件
*
* @param directory
* 下载目录
* @param downloadFile
* 下载文件名
* @param saveFile
* 存在本地的文件全路径
*/
public File downloadToFile(String directory, String downloadFile, String saveFile) {
try {
sftp.cd(directory);
File file = new File(saveFile);
FileOutputStream fileOutputStream = new FileOutputStream(file);
sftp.get(downloadFile, fileOutputStream);
fileOutputStream.close();
return file;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return null;
}
}
/**
*
* @param directory
* 下载目录
* @param downloadFile
* 下载文件名
* @param saveFilePath
* 存在本地的路径
* @return
*/
public File downloadToDirectory(String directory, String downloadFile, String saveFilePath) {
try {
sftp.cd(directory);
File file = new File(saveFilePath + File.separator + downloadFile);
FileOutputStream fileOutputStream = new FileOutputStream(file);
sftp.get(downloadFile, fileOutputStream);
fileOutputStream.close();
return file;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return null;
}
}
/**
* 下载文件
*
* @param downloadFilePath
* 下载的文件完整目录
* @param saveFile
* 存在本地的路径
*/
public File download(String downloadFilePath, String saveFile) {
try {
int i = downloadFilePath.lastIndexOf('/');
if (i == -1)
return null;
sftp.cd(downloadFilePath.substring(0, i));
File file = new File(saveFile);
FileOutputStream fileOutputStream = new FileOutputStream(file);
sftp.get(downloadFilePath.substring(i + 1), fileOutputStream);
fileOutputStream.close();
return file;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return null;
}
}
/**
* 关闭会话和通道
*/
public void disconnect() {
try {
sftp.getSession().disconnect();
} catch (JSchException e) {
logger.error(e.getMessage(), e);
}
sftp.quit();
sftp.disconnect();
}
/**
* 列出目录下的文件
*
* @param directory
* 要列出的目录
* @throws SftpException
*/
public Vector<LsEntry> listFiles(String directory) throws SftpException {
return sftp.ls(directory);
}
public static void main(String[] args) throws IOException {
Logger logger = LoggerFactory.getLogger(SFTPUtils.class);
String host = "zhangzhiqiang.net";
int port = 22;
String username = "silent";
String password = "Citic123!";
// 服务器端可供操作的目录
String serverDirectory = "/upload";
SFTPUtils sf = null;
try {
sf = SFTPUtils.getInstance(host, port, username, password);
sf.upload(serverDirectory, "C:\\Users\\waiti\\Desktop\\b.xls"); // 上传文件
sf.downloadToFile(serverDirectory, "b.java", "C:\\Users\\waiti\\Desktop\\b3.java");
sf.downloadToDirectory(serverDirectory, "b.java", "C:\\Users\\waiti\\Desktop");
Vector<LsEntry> files = sf.listFiles(serverDirectory); // 查看文件列表
if (files != null) {
for (LsEntry file : files) {
System.out.println(file.getFilename());
}
}
} catch (SftpException e) {
logger.error("SFTP Error!", e);
} finally {
if (sf != null) {
sf.disconnect();
}
}
}
}