import com.google.common.base.Strings;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.Vector;
/**
* @Description: SFTP客戶端
* @author gaoxiang
* @date 2019年2月22日 下午4:31:03
*/
public class SftpClient {
private final static Logger logger = LoggerFactory.getLogger(SftpClient.class);
private static String host = "ip地址";
private static String username = "用戶名";
private static String password = "密碼";
protected static String privateKey;// 密鑰文件路徑
protected static String passphrase;// 密鑰口令
private static int port = 22;
private static ChannelSftp sftp = null;
private static Session sshSession = null;
public SftpClient(String host, String username, String password) {
this.host = host;
this.username = username;
this.password = password;
}
public SftpClient(String host, String username, String password, int port) {
this.host = host;
this.username = username;
this.password = password;
this.port = port;
}
public SftpClient(String host, String username, String password, int port, String privateKey, String passphrase) {
this.host = host;
this.username = username;
this.password = password;
this.privateKey = privateKey;
this.passphrase = passphrase;
this.port = port;
}
public static void connect() {
JSch jsch = new JSch();
Channel channel = null;
try {
if (!StringUtils.isEmpty(privateKey)) {
// 使用密鑰驗(yàn)證方式,密鑰可以使有口令的密鑰,也可以是沒(méi)有口令的密鑰
if (!StringUtils.isEmpty(passphrase)) {
jsch.addIdentity(privateKey, passphrase);
} else {
jsch.addIdentity(privateKey);
}
}
sshSession = jsch.getSession(username, host, port);
if (!StringUtils.isEmpty(password)) {
sshSession.setPassword(password);
}
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");// do not verify host
// key
sshSession.setConfig(sshConfig);
// session.setTimeout(timeout);
// session.setServerAliveInterval(92000);
sshSession.connect();
// 參數(shù)sftp指明要打開(kāi)的連接是sftp連接
channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
} catch (JSchException e) {
logger.error("連接【" + host + ":" + port + "】異常", e);
}
}
/**
* 獲取連接
* @return channel
*/
public void connectWithException() throws Exception {
JSch jsch = new JSch();
Channel channel = null;
try {
if (!StringUtils.isEmpty(privateKey)) {
// 使用密鑰驗(yàn)證方式咐旧,密鑰可以使有口令的密鑰屋谭,也可以是沒(méi)有口令的密鑰
if (!StringUtils.isEmpty(passphrase)) {
jsch.addIdentity(privateKey, passphrase);
} else {
jsch.addIdentity(privateKey);
}
}
sshSession = jsch.getSession(username, host, port);
if (!StringUtils.isEmpty(password)) {
sshSession.setPassword(password);
}
Properties sshConfig = new Properties();
// do not verify host key
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
// session.setTimeout(timeout);
// session.setServerAliveInterval(92000);
sshSession.connect();
// 參數(shù)sftp指明要打開(kāi)的連接是sftp連接
channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
} catch (JSchException e) {
logger.error("連接【" + host + ":" + port + "】異常", e);
throw new Exception("Could not connect to :" + host + ":" + port);
}
}
/**
* 關(guān)閉資源
*/
public static void disconnect() {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
}
}
if (sshSession != null) {
if (sshSession.isConnected()) {
sshSession.disconnect();
}
}
}
/**
* sftp is connected
*
* @return
*/
public static boolean isConnected() {
return sftp != null && sftp.isConnected();
}
public InputStream downFile(String remotePath, String remoteFile) throws Exception {
try {
if (sftp == null)
connect();
sftp.cd(remotePath);
return sftp.get(remoteFile);
} catch (SftpException e) {
logger.error("文件下載失敗或文件不存在赠摇!", e);
throw e;
} finally {
// disconnect();
}
}
public byte[] downLoad(String remotePath, String remoteFile) throws Exception {
try {
if (sftp == null)
connect();
sftp.cd(remotePath);
InputStream input = sftp.get(remoteFile);
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[10485760];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
} catch (SftpException e) {
logger.error("文件下載失敗或文件不存在爷辙!", e);
} finally {
disconnect();
}
return null;
}
public static void main(String[] args){
downloadFile("/home/apollo/QDAMC01/receive/20180926/20","loan_detail_001.txt","D:/work/","20.txt");
}
/**
* 下載單個(gè)文件
*
* @param remoteFileName
* 下載文件名
* @param localPath
* 本地保存目錄(以路徑符號(hào)結(jié)束)
* @param localFileName
* 保存文件名
* @return
*/
public static synchronized boolean downloadFile(String remotePath, String remoteFileName, String localPath, String localFileName) {
logger.info(remotePath + "/" + remoteFileName + "/" + localPath + "/" + localFileName);
try {
if (sftp == null || !isConnected()) {
connect();
}
sftp.cd(remotePath);
File file = new File(localPath + localFileName);
mkdirs(localPath + localFileName);
sftp.get(remoteFileName, new FileOutputStream(file));
return true;
} catch (FileNotFoundException e) {
logger.error("不存在文件,Path:" + remotePath + ",file:" + remoteFileName, e);
} catch (SftpException e) {
logger.error("下載文件處理異常,Path:" + remotePath + ",file:" + remoteFileName, e);
} finally {
disconnect();
}
return false;
}
/**
* 上傳
*/
public void uploadFile(String remotePath, String fileName, InputStream input) throws IOException, Exception {
try {
if (sftp == null) {
connect();
}
// createDir(remotePath);
mkDir(remotePath.replace(sftp.pwd(), ""));// 絕對(duì)路徑變?yōu)橄鄬?duì)路徑
sftp.put(input, fileName);
} catch (Exception e) {
logger.error("文件上傳異常胚委!", e);
throw new Exception("文件上傳異常:" + e.getMessage());
} finally {
if (input != null) {
try {
input.close();
} catch (Exception e) {
}
}
// disconnect();
}
}
/**
* 上傳單個(gè)文件
*
* @param remotePath
* 遠(yuǎn)程保存目錄
* @param remoteFileName
* 保存文件名
* @param localPath
* 本地上傳目錄(以路徑符號(hào)結(jié)束)
* @param localFileName
* 上傳的文件名
* @return
*/
public boolean uploadFile(String remotePath, String remoteFileName, String localPath, String localFileName) {
File fileInput = new File(localPath + localFileName);
return uploadFile(remotePath, remoteFileName, fileInput);
}
/**
* 上傳單個(gè)文件
*
* @param remotePath
* 遠(yuǎn)程保存目錄
* @param remoteFileName
* 保存文件名
* @param fileInput
* 上傳的文件
* @return
*/
public boolean uploadFile(String remotePath, String remoteFileName, File fileInput) {
FileInputStream in = null;
try {
in = new FileInputStream(fileInput);
uploadFile(remotePath, remoteFileName, in);
return true;
} catch (Exception e) {
logger.error("上傳單個(gè)文件異常", e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
logger.warn("關(guān)閉sftp資源異常", e);
}
}
}
return false;
}
/**
* 創(chuàng)建目錄
*
* @param createpath
* @return
*/
private boolean createDir(String createpath) {
try {
if (isDirExist(createpath)) {
this.sftp.cd(createpath);
return true;
}
String[] pathArry = createpath.split("/");
StringBuffer filePath = new StringBuffer("/");
for (String path : pathArry) {
if (path.equals("")) {
continue;
}
filePath.append(path + "/");
if (isDirExist(filePath.toString())) {
sftp.cd(filePath.toString());
} else {
// 建立目錄
sftp.mkdir(filePath.toString());
// 進(jìn)入并設(shè)置為當(dāng)前目錄
sftp.cd(filePath.toString());
}
}
return true;
} catch (SftpException e) {
logger.error("sftp創(chuàng)建目錄異常", e);
}
return false;
}
/**
* 判斷目錄是否存在
*
* @param directory
* @return
*/
public boolean isDirExist(String directory) {
try {
SftpATTRS sftpATTRS = sftp.lstat(directory);
return sftpATTRS.isDir();
} catch (Exception e) {
// logger.error("sftp目錄isDirExist異常", e);
}
return false;
}
/**
* 如果目錄不存在就創(chuàng)建目錄
*
* @param path
*/
private static void mkdirs(String path) {
File f = new File(path);
String fs = f.getParent();
f = new File(fs);
if (!f.exists()) {
f.mkdirs();
}
}
public boolean deleteFile(String remotePath, String remoteFile) throws Exception {
try {
if (sftp == null)
connect();
if (openDir(remotePath)) {
sftp.rm(remoteFile);
}
return true;
} catch (SftpException e) {
logger.error("刪除文件【" + remotePath + "/" + remoteFile + "】發(fā)生異常课竣!", e);
throw e;
}
}
/**
* 創(chuàng)建文件夾
*
* @param dirName
*/
public void mkDir(String dirName) {
String[] dirs = dirName.split("/");
try {
String now = sftp.pwd();
for (int i = 0; i < dirs.length; i++) {
if (Strings.isNullOrEmpty(dirs[i]))
continue;
boolean dirExists = openDir(dirs[i]);
if (!dirExists) {
sftp.mkdir(dirs[i]);
sftp.cd(dirs[i]);
}
}
// 進(jìn)入當(dāng)前目錄
sftp.cd(now + "/" + dirName);
} catch (SftpException e) {
logger.error("mkDir Exception : " + e);
}
}
/**
* 打開(kāi)文件夾一層一層
*
* @param directory
* @return
*/
public boolean openDir(String directory) {
try {
logger.debug("opendir: {}", directory);
sftp.cd(directory);
return true;
} catch (SftpException e) {
logger.debug("openDir【" + directory + "】 Exception : " + e);
return false;
}
}
/**
* 獲取輸出的out put stream
*
* @param path
* @param name
* @return
* @throws Exception
*/
public OutputStream getUpLoadStream(String path, String name, String rcCode) throws Exception {
if (sftp == null || !isConnected()) {
connect();
}
String finalPath = path + rcCode;
synchronized (CREATE_PATH_LOCK) {
if (!openDir(finalPath)) {
createDir(finalPath);
}
}
sftp.cd(finalPath);
return sftp.put(name);
}
private static Object CREATE_PATH_LOCK = new Object();
public OutputStream getUpLoadStream(String path, String name) throws Exception {
if (sftp == null || !isConnected()) {
connect();
}
synchronized (CREATE_PATH_LOCK) {
if (!openDir(path)) {
createDir(path);
}
}
sftp.cd(path);
return sftp.put(name);
}
/**
* 上傳 不關(guān)閉任何流
*/
public void uploadFileNotClose(InputStream input, String remotePath, String fileName) throws IOException, Exception {
try {
if (sftp == null) {
connect();
}
if (!openDir(remotePath)) {
createDir(remotePath);
}
sftp.put(input, fileName);
} catch (Exception e) {
logger.error("文件上傳異常嘉赎!", e);
throw new Exception("文件上傳異常:" + e.getMessage());
}
}
/**
* 上傳(input上傳完成,并未關(guān)閉,在外層調(diào)用處虛處理)
*/
public void uploadFile(InputStream input, String remotePath, String fileName) throws IOException, Exception {
try {
if (sftp == null) {
connect();
}
if (!openDir(remotePath)) {
createDir(remotePath);
}
sftp.put(input, fileName);
} catch (Exception e) {
logger.error("文件上傳異常!", e);
throw new Exception("文件上傳異常:" + e.getMessage());
} finally {
if (input != null) {
try {
input.close();
} catch (Exception e) {
}
}
disconnect();
}
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public ChannelSftp getSftp() {
return sftp;
}
public void setSftp(ChannelSftp sftp) {
this.sftp = sftp;
}
@SuppressWarnings("unchecked")
public Vector<ChannelSftp.LsEntry> listFiles(String remotePath) throws Exception {
Vector<ChannelSftp.LsEntry> vector = null;
try {
if (sftp == null)
connect();
sftp.cd("/");
vector = sftp.ls(remotePath);
} catch (SftpException e) {
throw new Exception("list file error.", e);
}
return vector;
}
/**
* 判斷文件是否存在
* @param directory
* @return
*/
public boolean isFileExist(String directory) {
boolean isDirExistFlag = false;
try {
if (sftp == null)
connect();
sftp.lstat(directory);
isDirExistFlag = true;
} catch (Exception e) {
isDirExistFlag = false;
}
return isDirExistFlag;
}
}
java實(shí)現(xiàn)SFTP服務(wù)器上傳下載
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)队寇,“玉大人膘掰,你說(shuō)我怎么就攤上這事〖亚玻” “怎么了识埋?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)零渐。 經(jīng)常有香客問(wèn)我窒舟,道長(zhǎng),這世上最難降的妖魔是什么诵盼? 我笑而不...
- 正文 為了忘掉前任辜纲,我火速辦了婚禮,結(jié)果婚禮上拦耐,老公的妹妹穿的比我還像新娘耕腾。我一直安慰自己,他們只是感情好杀糯,可當(dāng)我...
- 文/花漫 我一把揭開(kāi)白布扫俺。 她就那樣靜靜地躺著,像睡著了一般固翰。 火紅的嫁衣襯著肌膚如雪狼纬。 梳的紋絲不亂的頭發(fā)上,一...
- 那天骂际,我揣著相機(jī)與錄音疗琉,去河邊找鬼。 笑死歉铝,一個(gè)胖子當(dāng)著我的面吹牛盈简,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播太示,決...
- 文/蒼蘭香墨 我猛地睜開(kāi)眼柠贤,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了类缤?” 一聲冷哼從身側(cè)響起臼勉,我...
- 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎餐弱,沒(méi)想到半個(gè)月后宴霸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體囱晴,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年瓢谢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了畸写。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
- 正文 年R本政府宣布翅楼,位于F島的核電站尉剩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏毅臊。R本人自食惡果不足惜理茎,卻給世界環(huán)境...
- 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望管嬉。 院中可真熱鬧皂林,春花似錦、人聲如沸蚯撩。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)胎挎。三九已至沟启,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間犹菇,已是汗流浹背德迹。 一陣腳步聲響...
- 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像称杨,于是被迫代替她去往敵國(guó)和親流酬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 最近在搞關(guān)于搭建ftp服務(wù)器并需要實(shí)現(xiàn)上傳下載功能,而且項(xiàng)目比較著急页衙,所以在盡量簡(jiǎn)化工作量的情況下實(shí)現(xiàn)目標(biāo)摊滔,同時(shí)參...
- 一般買(mǎi)來(lái)一個(gè)新的服務(wù)器,安裝好操作系統(tǒng)之后,需要安裝一系列的插件.這里總結(jié)一下lrzsz插件的安裝方法. 1. 登...
- 為了讓實(shí)驗(yàn)室同學(xué)在共享文件時(shí)更加方便阴绢,我們決定在實(shí)驗(yàn)室電腦上搭建一個(gè)FTP服務(wù)器,ubuntu系統(tǒng)版本為16.04...
- Part 1 In this chapter, the author talked about the child...