Sftp私钥或密码连接-上传下载、获取sftp上文件的内容

import java.io.*;
import java.util.*;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

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.SftpATTRS;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.UserInfo;
import com.peony.provisioncheck.constant.Constant;

@Component
public class SFTPUtil {
private transient Logger log = LoggerFactory.getLogger(this.getClass());
private ChannelSftp sftp;
private Session session;
/**
* FTP 登录用户名
*/
private String username;
/**
* FTP 登录密码
*/
private String password;
/**
* 私钥
*/
private String privateKey;

private String keyPwd;

/**
* FTP 服务器地址IP地址
*/
private String host;

private int port;

/**
* 构造基于密码认证的sftp对象
*
* @param username
* @param password
* @param host
* @param port
*/
public SFTPUtil(String username, String password, String host, int port, String privateKey) {
this.username = username;
this.password = password;
this.host = host;
this.port = port;
this.privateKey = privateKey;
this.keyPwd = password;
}

/**
* 构造基于秘钥认证的sftp对象
*/
// public SFTPUtil(String username, String host, int port, String privateKey) {
// this.username = username;
// this.host = host;
// this.port = port;
// this.privateKey = privateKey;
// }
public SFTPUtil() {
}

/**
* 连接sftp服务器
*
* @throws Exception
*/
public void login() {
try {
if (null == sftp) {
System.out.println("======>" + host + port + username + privateKey + keyPwd);
sftp = SFTPUtil.privateKeyConnect(host, port, username, privateKey, keyPwd);
}
if (null == sftp) {
JSch jsch = new JSch();
if (privateKey != null) {
try {
jsch.addIdentity(privateKey);// 设置私钥
} catch (JSchException e) {
e.printStackTrace();
}
log.info("sftp connect,path of private key file{}", privateKey);
}
log.info("sftp connect by host:{} username:{}", host, username);

session = jsch.getSession(username, host, port);
log.info("Session is build");
if (password != null) {
session.setPassword(password);
}
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");

session.setConfig(config);
session.connect();
log.info("Session is connected");

Channel channel = session.openChannel("sftp");
channel.connect();
log.info("channel is connected");
sftp = (ChannelSftp) channel;
log.info(String.format("sftp server host:[%s] port:[%s] is connect successfull", host, port));
}
} catch (JSchException e) {
log.error("Cannot connect to specified sftp server : {}:{} \n Exception message is: {}",
new Object[]{host, port, e.getMessage()});
}
}

/**
* 关闭连接 server
*/
public void logout() {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
log.info("sftp is closed already");
}
}
if (session != null) {
if (session.isConnected()) {
session.disconnect();
log.info("sshSession is closed already");
}
}
}
/**
* 获取sftp 文件内容
*
* @param fileName
* @param ftpPath
* @return
* @throws SftpException
* @throws IOException
*/
public List<String> getFtpData(String fileName, String ftpPath) throws SftpException, IOException {
try {
if (null == sftp) {
return null;
}
sftp.cd(ftpPath);
} catch (Exception e) {
e.printStackTrace();
}
List<String> list = new ArrayList<>();
InputStream in = sftp.get(fileName);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
// StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
// sb.append(line+"\n");
list.add(line);
}
// return sb.toString();
return list;
}

/**
* 将输入流的数据上传到sftp作为文件
*
* @param directory 上传到该目录
* @param sftpFileName sftp端文件名
* @param input 输入流
* @throws SftpException
* @throws Exception
*/
public void upload(String directory, String sftpFileName, InputStream input) throws SftpException {
try {
sftp.cd(directory);
} catch (SftpException e) {
log.warn("directory is not exist");
sftp.mkdir(directory);
sftp.cd(directory);
}
sftp.put(input, sftpFileName);
log.info("file:{} is upload successful", sftpFileName);
}

/**
* 上传单个文件
*
* @param directory 上传到sftp目录
* @param uploadFile 要上传的文件,包括路径
* @throws   FileNotFoundException
* @throws SftpException
* @throws Exception
*/
public void upload(String directory, String uploadFile) throws FileNotFoundException, SftpException {       File file =
new File(uploadFile);
upload(directory, file.getName(), new FileInputStream(file));
}

public void cdDir(String directory) throws FileNotFoundException, SftpException {
  try {
      sftp.cd(directory);
} catch (SftpException e) {
      log.warn("directory is not exist");
      sftp.mkdir(directory);
      sftp.cd(directory);
} }



/**
* 上传单个文件
*
* @throws FileNotFoundException
* @throws SftpException
* @throws Exception
*/
public void upload(File file) throws FileNotFoundException, SftpException {
    sftp.put(new FileInputStream(file), file.getName());
}

/**
* byte[]上传到sftp,作为文件。注意:String生成byte[]是,要指定字符集。
*
* @param directory 上传到sftp目录
* @param sftpFileName 文件在sftp端的命名
* @param byteArr 要上传的字节数组
* @throws SftpException
* @throws Exception
*/
public void upload(String directory, String sftpFileName, byte[] byteArr) throws SftpException {     upload(directory
, sftpFileName, new ByteArrayInputStream(byteArr));
}

/**
* 将字符串按照指定的字符编码上传到sftp
*
* @param directory 上传到sftp目录
* @param sftpFileName 文件在sftp端的命名
* @param dataStr 待上传的数据
* @param charsetName sftp上的文件,按该字符编码保存
* @throws UnsupportedEncodingException
* @throws SftpException
* @throws Exception
*/
public void upload(String directory, String sftpFileName, String dataStr, String charsetName)
throws UnsupportedEncodingException, SftpException { upload(directory
, sftpFileName, new ByteArrayInputStream(dataStr.getBytes(charsetName)));
}

/**
* 批量下载文件 保存在本地
*
* @param remotPath 远程下载目录
* @param localPath 本地保存目录
* @return
*/
public boolean batchDownLoadFile(String remotPath, String localPath) throws FileNotFoundException {
try { Vector v = listFiles(remotPath)
;
if (v.size() > 0) { Iterator it = v.iterator()
;
while (it.hasNext()) { ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) it.next()
;
String filename = entry.getFilename();
SftpATTRS attrs = entry.getAttrs();
if (!attrs.isDir()) {
this.download(remotPath, filename, localPath);
} } } }


catch (SftpException e) { e.printStackTrace()
;
} catch (IOException ioe) { ioe.printStackTrace()
;
}
return false;
}

/**
* 下载文件
*
* @param directory 下载目录
* @param downloadFile 下载的文件
* @param saveFile 存在本地的路径
* @throws SftpException
* @throws FileNotFoundException
* @throws Exception
*/
public void download(String directory, String downloadFile, String saveFile)
throws SftpException, FileNotFoundException {
log.info(" directory = " + directory);
if (directory != null && !"".equals(directory)) {
sftp.cd(directory);
} mkdirs(saveFile +
"/" + downloadFile);
File file = new File(saveFile + "/" + downloadFile);
sftp.get(downloadFile, new FileOutputStream(file));
log.info("file:{} is download successful", downloadFile);
}

/**
* 下载文件
*
* @param directory 下载目录
* @param downloadFile 下载的文件名
* @return 字节数组
* @throws SftpException
* @throws IOException
* @throws Exception
*/
public byte[] download(String directory, String downloadFile) throws SftpException, IOException {
if (directory != null && !"".equals(directory)) {
sftp.cd(directory);
} InputStream is =
sftp.get(downloadFile);

byte[] fileData = IOUtils.toByteArray(is);

log.info("file:{} is download successful", downloadFile);
return fileData;
}

/**
* 删除文件
*
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
* @throws SftpException
* @throws Exception
*/
public void delete(String directory, String deleteFile) throws SftpException {
sftp.cd(directory);
sftp.rm(deleteFile);
}

/**
* 列出目录下的文件
*
* @param directory 要列出的目录
* @return
* @throws SftpException
*/
public Vector<?> listFiles(String directory) throws SftpException {
return sftp.ls(directory);
}

/**
* 创建目录
*
* @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()
;
} }


/**
* 检查SFTP服务器上某个目录下是否有指定目录或文件
*
* @param dir 验检查的目录
* @param fileName 检查是否存在的文件名
* @param isFile true:文件,false:文件夹
* @throws IOException
* @throws SftpException
*/
public boolean hasFileOrDir(String dir, String fileName, boolean isFile) throws SftpException { Vector fileList =
sftp.ls(dir);
if (null == fileList || fileList.size() <= 0) {
return false;
} Iterator it = fileList.iterator()
;
while (it.hasNext()) { String tmpName = ((LsEntry) it.next()).getFilename()
;
if (".".equals(tmpName) || "..".equals(tmpName)) {
continue;
}
if (fileName.equals(tmpName)) { String filePath
;
if (dir.equals(Constant.LINUX_DIR_SPLIT)) { filePath = dir + fileName
;
} else { filePath = dir + Constant.
LINUX_DIR_SPLIT + fileName;
}
if (isFile) {
if (!sftp.stat(filePath).isDir()) {
return true;
} }
else {
if (sftp.stat(filePath).isDir()) {
return true;
} } } }




return false;
}

/**
* 有没有包含指定字符串的文件
*
* @param dir 文件夹
* @param str 文件名包含的字符串
* @throws SftpException
*/
public boolean hasContainsFile(String dir, String str) throws SftpException { Vector fileList =
sftp.ls(dir);
if (null == fileList || fileList.size() <= 0) {
return false;
} Iterator it = fileList.iterator()
;
while (it.hasNext()) { String tmpName = ((LsEntry) it.next()).getFilename()
;
if (".".equals(tmpName) || "..".equals(tmpName)) {
continue;
}
if (tmpName.contains(str)) { String filePath
;
if (dir.equals(Constant.LINUX_DIR_SPLIT)) { filePath = dir + tmpName
;
} else { filePath = dir + Constant.
LINUX_DIR_SPLIT + tmpName;
}
if (!sftp.stat(filePath).isDir()) {
return true;
} } }



return false;
}

/**
* 获取包含指定字符串的文件名
*
* @param dir 文件夹
* @param str 文件名包含的字符串
* @throws SftpException
*/
public String getContainsFile(String dir, String str) throws SftpException { Vector fileList =
sftp.ls(dir);
if (null == fileList || fileList.size() <= 0) {
return null;
} Iterator it = fileList.iterator()
;
while (it.hasNext()) { String tmpName = ((LsEntry) it.next()).getFilename()
;
if (".".equals(tmpName) || "..".equals(tmpName)) {
continue;
}
if (tmpName.contains(str)) { String filePath
;
if (dir.equals(Constant.LINUX_DIR_SPLIT)) { filePath = dir + tmpName
;
} else { filePath = dir + Constant.
LINUX_DIR_SPLIT + tmpName;
}
if (!sftp.stat(filePath).isDir()) {
return tmpName;
} } }



return null;
}

// 从网联的sftp服务器获取文件

/**
* 私钥连接sftp服务器.
*
* @param host 服务器地址
* @param port 服务器端口
* @param username 用户名
* @param passphrase 私钥密码-通行码
* @return sftp
*/
public static ChannelSftp privateKeyConnect(String host, int port, String username, String privateKey, String passphrase) {      ChannelSftp sftp =
null;
try {    JSch jsch =
new JSch();
jsch.addIdentity(privateKey);// 设置私钥
Session sshSession = jsch.getSession(username, host, port);
System.out.println("Session创建完成 MIMA" + passphrase + " pri:" + privateKey);
UserInfo ui = new MyUserInfo(passphrase);
sshSession.setUserInfo(ui);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
System.out.println("Session链接完成");
System.out.println("开启通道");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
System.out.println("私钥******%%%%%%%连接上了sftp服务器" + host + ":" + port);
} catch (Exception e) {   System.
out.println("私钥******连接sftp服务器时出错!" + "host:" + host + ";port:" + port);
}
      return sftp;
}

public static class MyUserInfo implements UserInfo {
private String passphrase = null;

public MyUserInfo(String passphrase) {
this.passphrase = passphrase;
}

public String getPassphrase() {
return passphrase;
}

public String getPassword() {
return null;
}

public boolean promptPassphrase(String s) {
return true;
}

public boolean promptPassword(String s) {
return true;
}

public boolean promptYesNo(String s) {
return true;
}

public void showMessage(String s) {     System.
out.println(s);
} }}





posted @   SevenStar  阅读(207)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
点击右上角即可分享
微信分享提示