java语言连接sftp服务器的一些总结
程序员文章站
2022-04-28 21:54:35
...
写道
package com.zznode.ngn.sa.psm.probe.sftp;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
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.SftpATTRS;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.sshtools.vfs.SftpClientFactory;
import com.zznode.e2e.log.Logger;
/**
* SFTP客户端工具,提供从远程服务器下载文件功能
* apache 类包应用
*/
public class SftpClient {
private static final Logger logger = Logger.getLogger(SftpClient.class);
/**
* FTP客户端,实现从服务器上下载文件。
*/
private ChannelSftp sftp;
private Session sshSession;
private String userName;
private String password;
private String hostName;
private int port;
/**
* 密钥文件路径
*/
private String privateKey;
/**
* 密钥的密码
*/
private String passphrase;
public SftpClient(String hostName, int port, String userName, String password) {
this.hostName = hostName;
this.port = port;
this.userName = userName;
this.password = password;
sftp=new ChannelSftp();
}
/**
* 使用密钥方式
* @param hostName
* @param port
* @param userName
* @param privateKey
* @param passphrase
*/
public SftpClient(String hostName, int port, String userName, String privateKey,String passphrase) {
this.hostName = hostName;
this.port = port;
this.userName = userName;
this.privateKey = privateKey;
this.passphrase = passphrase;
sftp=new ChannelSftp();
}
/**
* 连接sftp服务器
* @param host 主机
* @param port 端口
* @param username 用户名
* @param password 密码
* @return
*/
public synchronized void login(){
try {
// SFTPUtil sftputil = new SFTPUtil(userName,password,hostName,port);
// sftp = sftputil.connectServer();
com.jcraft.jsch.Logger jslogger = new SettleLogger();
JSch.setLogger(jslogger);
JSch jsch = new JSch();
sshSession = jsch.getSession(userName, hostName, port); // 根据用户名,主机ip,端口获取一个Session对象
Properties sshConfig = new Properties();// 为Session对象设置properties
sshConfig.put("StrictHostKeyChecking", "no");
logger.debug("--->password:"+password);
sshSession.setPassword(password);// 设置密码
sshSession.setConfig(sshConfig);
sshSession.setTimeout(30000); // 设置timeout时间
sshSession.connect(); // 通过Session建立链接
Channel channel = sshSession.openChannel("sftp");
channel.connect();// 建立SFTP通道的连接
sftp = (ChannelSftp) channel;
logger.info("Connected to sftp " + hostName + " sucess !!!");
} catch (Exception e) {
StringBuffer msg = new StringBuffer();
msg.append("Cannot connect to sftp server '");
msg.append(hostName + ":" + port).append("', cause by ");
msg.append(e.getMessage());
logger.error(msg.toString());
e.printStackTrace();
}
}
/**
* 连接sftp服务器
* 使用RSA密钥方式
*/
public synchronized void login4RSA(){
com.jcraft.jsch.Logger jslogger = new SettleLogger();
JSch.setLogger(jslogger);
Channel channel = null;
JSch jsch = new JSch();
//设置密钥和密码
try {
if(privateKey != null && !"".equals(privateKey)){
if(passphrase != null && !"".equals(passphrase)){
jsch.addIdentity(privateKey, passphrase);
}else{
jsch.addIdentity(privateKey);
}
}else{
throw new Exception("privateKey is null or empty!");
}
if(port <= 0){
sshSession = jsch.getSession(userName, hostName);
}else{
sshSession = jsch.getSession(userName, hostName, port);
}
if(password != null && !password.equals("")){
sshSession.setPassword(password);
}
sshSession.setConfig("StrictHostKeyChecking", "no");
sshSession.connect();
channel = sshSession.openChannel("sftp");
channel.connect();// 建立SFTP通道的连接
sftp = (ChannelSftp) channel;
logger.info("Connected to sftp " + hostName + " sucess !!!");
} catch (Exception e) {
logger.debug("--->error!!!"+e);
e.printStackTrace();
}
}
/**
* 注销登录,并断开到SFTP服务器的网络连接
*/
public synchronized void logout() {
if (sftp != null && sftp.isConnected()) {
sftp.disconnect();
logger.info("sftp is closed !!!");
}
if(sshSession!=null && sshSession.isConnected()){
sshSession.disconnect();
logger.info("sshSession is closed !!!");
}
}
/**
* 判断sftp是否连接
* @return
*/
public synchronized boolean isConnected()
{
if(sftp!=null)
{
return sftp.isConnected();
}
return false;
}
/**
* 列出dir路径下的文件
* @param dir
* @return
*/
public synchronized String[] listFileNames(String dir){
try {
Vector v = sftp.ls(dir);
String[] names;
if(v != null && v.size()>0){
int count = v.size();
names = new String[count];
for(int i = 0;i < count;i++){
LsEntry lsEnt = (LsEntry)v.get(i);
names[i] = lsEnt.getFilename();
}
logger.debug("-->"+dir+" contain file number "+count);
return names;
}else{
return null;
}
} catch (SftpException e) {
e.printStackTrace();
return null;
}
}
/**
* 上传文件
* @param directory 上传的目录
* @param uploadFile 要上传的文件
* @param sftp
*/
public void upload(String remotePath, String sftpFileName, String localPath, String fileName) {
try {
sftp.cd(remotePath);
File file=new File(localPath+fileName);
sftp.put(new FileInputStream(file), sftpFileName);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 批量上传文件
* @param remotePath 远程保存目录
* @param localPath 本地上传目录(以路径符号结束)
* @param del 上传后是否删除本地文件
* @return
*/
public boolean bacthUploadFile(String remotePath, String localPath, boolean del) {
try {
File file = new File(localPath);
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile() && files[i].getName().indexOf("bak") == -1) {
upload(remotePath, files[i].getName(),localPath, files[i].getName());
if (del) {
deleteFile(localPath + files[i].getName());
}
}
}
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
logout();
}
return false;
}
/**
* 下载文件
* @param directory 下载目录
* @param downloadFile 下载的文件
* @param saveFile 存在本地的路径
* @param sftp
*/
public boolean download(String directory, String downloadFile, String localPath, String saveFile) {
try {
sftp.cd(directory);
if(localPath!=null){
saveFile=localPath + saveFile;
}
File file=new File(saveFile);
mkdirs(saveFile);
sftp.get(downloadFile, new FileOutputStream(file));
return true;
} catch (Exception e) {
logger.error("no such file:"+downloadFile);
return false;
// e.printStackTrace();
}
}
/**
* 下载文件
* @param localFile
* @param remoteFile
* @return
*/
public boolean download(String localFile, String remoteFile){
String remoteFileName = remoteFile.substring(remoteFile.lastIndexOf("\\")+1);
String remoteDir = remoteFile.substring(0, remoteFile.lastIndexOf("\\"));
String localFileName = localFile.substring(localFile.lastIndexOf("\\")+1);
String localDir = localFile.substring(0, localFile.lastIndexOf("\\"));
logger.debug("-->ready to download the file "+remoteFileName+" from "+remoteDir+"... download to "+localDir+" "+localFileName);
return this.download(remoteDir, remoteFileName, localDir, localFileName);
}
/**
* 批量下载文件
*@param remotPath 远程下载目录(以路径符号结束)
* @param localPath 本地保存目录(以路径符号结束)
* @param fileFormat 下载文件格式(以特定字符开头,为空不做检验)
* @param del 下载后是否删除sftp文件
* @return
*/
public boolean batchDownLoadFile(String remotPath, String localPath, String fileFormat, boolean del) {
try {
Vector v = listFiles(remotPath);
for(Iterator it = v.iterator();it.hasNext();) {
LsEntry entry = (LsEntry) it.next();
String filename = entry.getFilename();
SftpATTRS attrs = entry.getAttrs();
if (!attrs.isDir()) {
if (fileFormat != null && !"".equals(fileFormat.trim())) {
if (filename.startsWith(fileFormat)) {
download(remotPath, filename, localPath, filename);
if (del) {
deleteSftpFile(remotPath, filename);
}
}
} else {
download(remotPath, filename,localPath, filename);
if (del) {
deleteSftpFile(remotPath, filename);
}
}
}
}
return true;
} catch (SftpException e) {
e.printStackTrace();
} finally {
logout();
}
return false;
}
/**
* 如果目录不存在就创建目录
*@param path
*/
public void mkdirs(String path) {
File f = new File(path);
String fs = f.getParent();
f = new File(fs);
if (!f.exists()) {
f.mkdirs();
}
}
/**
* 删除服务器文件
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
* @param sftp
*/
public void deleteSftpFile(String directory, String deleteFile) {
try {
sftp.cd(directory);
sftp.rm(deleteFile);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 删除本地文件
* @param filePath
*
*/
public boolean deleteFile(String filePath) {
File file = new File(filePath);
if (!file.exists()) {
return false;
}
if (!file.isFile()) {
return false;
}
return file.delete();
}
/**
* 列出目录下的文件名
* @param directory 要列出的目录
* @param sftp
* @return
* @throws SftpException
*/
public Vector listFiles(String directory) throws SftpException{
return sftp.ls(directory);
}
public static void main(String[] args) throws SftpException {
SftpClient sf = new SftpClient("58.248.11.212",22,"wnm_rms","Rms#2013");
String directory = "/home/wnm_rms/";
String uploadFile = "D:\\tmp\\upload.txt";
String downloadFile = "upload.txt";
String saveFile = "D:\\tmp\\download.txt";
String deleteFile = "delete.txt";
sf.login();
// ChannelSftp sftp=sf.sftp;
Vector cc=sf.listFiles(directory);
for(Iterator ii=cc.iterator();ii.hasNext();){
System.out.println(ii.next());
}
// sf.upload(directory, uploadFile);
// sf.download(directory, downloadFile, saveFile);
// sf.delete(directory, deleteFile);
try{
}catch(Exception e){
e.printStackTrace();
}
}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
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.SftpATTRS;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.sshtools.vfs.SftpClientFactory;
import com.zznode.e2e.log.Logger;
/**
* SFTP客户端工具,提供从远程服务器下载文件功能
* apache 类包应用
*/
public class SftpClient {
private static final Logger logger = Logger.getLogger(SftpClient.class);
/**
* FTP客户端,实现从服务器上下载文件。
*/
private ChannelSftp sftp;
private Session sshSession;
private String userName;
private String password;
private String hostName;
private int port;
/**
* 密钥文件路径
*/
private String privateKey;
/**
* 密钥的密码
*/
private String passphrase;
public SftpClient(String hostName, int port, String userName, String password) {
this.hostName = hostName;
this.port = port;
this.userName = userName;
this.password = password;
sftp=new ChannelSftp();
}
/**
* 使用密钥方式
* @param hostName
* @param port
* @param userName
* @param privateKey
* @param passphrase
*/
public SftpClient(String hostName, int port, String userName, String privateKey,String passphrase) {
this.hostName = hostName;
this.port = port;
this.userName = userName;
this.privateKey = privateKey;
this.passphrase = passphrase;
sftp=new ChannelSftp();
}
/**
* 连接sftp服务器
* @param host 主机
* @param port 端口
* @param username 用户名
* @param password 密码
* @return
*/
public synchronized void login(){
try {
// SFTPUtil sftputil = new SFTPUtil(userName,password,hostName,port);
// sftp = sftputil.connectServer();
com.jcraft.jsch.Logger jslogger = new SettleLogger();
JSch.setLogger(jslogger);
JSch jsch = new JSch();
sshSession = jsch.getSession(userName, hostName, port); // 根据用户名,主机ip,端口获取一个Session对象
Properties sshConfig = new Properties();// 为Session对象设置properties
sshConfig.put("StrictHostKeyChecking", "no");
logger.debug("--->password:"+password);
sshSession.setPassword(password);// 设置密码
sshSession.setConfig(sshConfig);
sshSession.setTimeout(30000); // 设置timeout时间
sshSession.connect(); // 通过Session建立链接
Channel channel = sshSession.openChannel("sftp");
channel.connect();// 建立SFTP通道的连接
sftp = (ChannelSftp) channel;
logger.info("Connected to sftp " + hostName + " sucess !!!");
} catch (Exception e) {
StringBuffer msg = new StringBuffer();
msg.append("Cannot connect to sftp server '");
msg.append(hostName + ":" + port).append("', cause by ");
msg.append(e.getMessage());
logger.error(msg.toString());
e.printStackTrace();
}
}
/**
* 连接sftp服务器
* 使用RSA密钥方式
*/
public synchronized void login4RSA(){
com.jcraft.jsch.Logger jslogger = new SettleLogger();
JSch.setLogger(jslogger);
Channel channel = null;
JSch jsch = new JSch();
//设置密钥和密码
try {
if(privateKey != null && !"".equals(privateKey)){
if(passphrase != null && !"".equals(passphrase)){
jsch.addIdentity(privateKey, passphrase);
}else{
jsch.addIdentity(privateKey);
}
}else{
throw new Exception("privateKey is null or empty!");
}
if(port <= 0){
sshSession = jsch.getSession(userName, hostName);
}else{
sshSession = jsch.getSession(userName, hostName, port);
}
if(password != null && !password.equals("")){
sshSession.setPassword(password);
}
sshSession.setConfig("StrictHostKeyChecking", "no");
sshSession.connect();
channel = sshSession.openChannel("sftp");
channel.connect();// 建立SFTP通道的连接
sftp = (ChannelSftp) channel;
logger.info("Connected to sftp " + hostName + " sucess !!!");
} catch (Exception e) {
logger.debug("--->error!!!"+e);
e.printStackTrace();
}
}
/**
* 注销登录,并断开到SFTP服务器的网络连接
*/
public synchronized void logout() {
if (sftp != null && sftp.isConnected()) {
sftp.disconnect();
logger.info("sftp is closed !!!");
}
if(sshSession!=null && sshSession.isConnected()){
sshSession.disconnect();
logger.info("sshSession is closed !!!");
}
}
/**
* 判断sftp是否连接
* @return
*/
public synchronized boolean isConnected()
{
if(sftp!=null)
{
return sftp.isConnected();
}
return false;
}
/**
* 列出dir路径下的文件
* @param dir
* @return
*/
public synchronized String[] listFileNames(String dir){
try {
Vector v = sftp.ls(dir);
String[] names;
if(v != null && v.size()>0){
int count = v.size();
names = new String[count];
for(int i = 0;i < count;i++){
LsEntry lsEnt = (LsEntry)v.get(i);
names[i] = lsEnt.getFilename();
}
logger.debug("-->"+dir+" contain file number "+count);
return names;
}else{
return null;
}
} catch (SftpException e) {
e.printStackTrace();
return null;
}
}
/**
* 上传文件
* @param directory 上传的目录
* @param uploadFile 要上传的文件
* @param sftp
*/
public void upload(String remotePath, String sftpFileName, String localPath, String fileName) {
try {
sftp.cd(remotePath);
File file=new File(localPath+fileName);
sftp.put(new FileInputStream(file), sftpFileName);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 批量上传文件
* @param remotePath 远程保存目录
* @param localPath 本地上传目录(以路径符号结束)
* @param del 上传后是否删除本地文件
* @return
*/
public boolean bacthUploadFile(String remotePath, String localPath, boolean del) {
try {
File file = new File(localPath);
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile() && files[i].getName().indexOf("bak") == -1) {
upload(remotePath, files[i].getName(),localPath, files[i].getName());
if (del) {
deleteFile(localPath + files[i].getName());
}
}
}
return true;
} catch (Exception e) {
e.printStackTrace();
} finally {
logout();
}
return false;
}
/**
* 下载文件
* @param directory 下载目录
* @param downloadFile 下载的文件
* @param saveFile 存在本地的路径
* @param sftp
*/
public boolean download(String directory, String downloadFile, String localPath, String saveFile) {
try {
sftp.cd(directory);
if(localPath!=null){
saveFile=localPath + saveFile;
}
File file=new File(saveFile);
mkdirs(saveFile);
sftp.get(downloadFile, new FileOutputStream(file));
return true;
} catch (Exception e) {
logger.error("no such file:"+downloadFile);
return false;
// e.printStackTrace();
}
}
/**
* 下载文件
* @param localFile
* @param remoteFile
* @return
*/
public boolean download(String localFile, String remoteFile){
String remoteFileName = remoteFile.substring(remoteFile.lastIndexOf("\\")+1);
String remoteDir = remoteFile.substring(0, remoteFile.lastIndexOf("\\"));
String localFileName = localFile.substring(localFile.lastIndexOf("\\")+1);
String localDir = localFile.substring(0, localFile.lastIndexOf("\\"));
logger.debug("-->ready to download the file "+remoteFileName+" from "+remoteDir+"... download to "+localDir+" "+localFileName);
return this.download(remoteDir, remoteFileName, localDir, localFileName);
}
/**
* 批量下载文件
*@param remotPath 远程下载目录(以路径符号结束)
* @param localPath 本地保存目录(以路径符号结束)
* @param fileFormat 下载文件格式(以特定字符开头,为空不做检验)
* @param del 下载后是否删除sftp文件
* @return
*/
public boolean batchDownLoadFile(String remotPath, String localPath, String fileFormat, boolean del) {
try {
Vector v = listFiles(remotPath);
for(Iterator it = v.iterator();it.hasNext();) {
LsEntry entry = (LsEntry) it.next();
String filename = entry.getFilename();
SftpATTRS attrs = entry.getAttrs();
if (!attrs.isDir()) {
if (fileFormat != null && !"".equals(fileFormat.trim())) {
if (filename.startsWith(fileFormat)) {
download(remotPath, filename, localPath, filename);
if (del) {
deleteSftpFile(remotPath, filename);
}
}
} else {
download(remotPath, filename,localPath, filename);
if (del) {
deleteSftpFile(remotPath, filename);
}
}
}
}
return true;
} catch (SftpException e) {
e.printStackTrace();
} finally {
logout();
}
return false;
}
/**
* 如果目录不存在就创建目录
*@param path
*/
public void mkdirs(String path) {
File f = new File(path);
String fs = f.getParent();
f = new File(fs);
if (!f.exists()) {
f.mkdirs();
}
}
/**
* 删除服务器文件
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
* @param sftp
*/
public void deleteSftpFile(String directory, String deleteFile) {
try {
sftp.cd(directory);
sftp.rm(deleteFile);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 删除本地文件
* @param filePath
*
*/
public boolean deleteFile(String filePath) {
File file = new File(filePath);
if (!file.exists()) {
return false;
}
if (!file.isFile()) {
return false;
}
return file.delete();
}
/**
* 列出目录下的文件名
* @param directory 要列出的目录
* @param sftp
* @return
* @throws SftpException
*/
public Vector listFiles(String directory) throws SftpException{
return sftp.ls(directory);
}
public static void main(String[] args) throws SftpException {
SftpClient sf = new SftpClient("58.248.11.212",22,"wnm_rms","Rms#2013");
String directory = "/home/wnm_rms/";
String uploadFile = "D:\\tmp\\upload.txt";
String downloadFile = "upload.txt";
String saveFile = "D:\\tmp\\download.txt";
String deleteFile = "delete.txt";
sf.login();
// ChannelSftp sftp=sf.sftp;
Vector cc=sf.listFiles(directory);
for(Iterator ii=cc.iterator();ii.hasNext();){
System.out.println(ii.next());
}
// sf.upload(directory, uploadFile);
// sf.download(directory, downloadFile, saveFile);
// sf.delete(directory, deleteFile);
try{
}catch(Exception e){
e.printStackTrace();
}
}
}
最近在工作中用户提出需求,从服务器下载文件,不能使用ftp必须使用sftp。原因是该服务器不支持ftp连接。然后我从网上找了一些例子,自己动手写出来了。
现记录下来以便自己以后回顾以及跟大家分享:
对于上面这个工具类做个简单的分析:
1、sftp类涉及到的第三方工具包:最主要的包是jsch-0.1.39.jar,还有一个打日志的包e2elog.jar包(公司内部封装的,便于排错的,没啥大用)
2、支持登录sftp的方式:
2.1、密码登录方式(login())
2.2、密钥登录方式(login4RSA())
3、sftp的一些简单操作:比如列出服务器上的文件,下载文件,上传文件等等,这些具体见代码
4、有啥不明白的欢迎留言,希望和大家多多讨论,共同进步