package com.wyl.modules.interfaces.bizaccount.util.sftp;
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.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Vector;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.wyl.modules.interfaces.bizaccount.util.SYSDICTPARA;
import com.wyl.modules.platform.sysconfig.service.SysConfigService;
import com.wyl.platform.core.common.SpringContextUtil;
public class SFTPUtil {
private static final Logger logger = LoggerFactory.getLogger(SFTPUtil.class);
private ChannelSftp sftp = null;
private Session sshSession = null;
public static void main(String[] args){
Map<String, String> destFtp=new HashMap<String,String>();
destFtp.put("destFtpIp", "192.168.232.145");
destFtp.put("destftpPort", "21");
destFtp.put("destUserName", "ftpuser");
destFtp.put("destPassWord", "12345678");
// destFtp.put("destFilePath","/upload");
// System.out.println("start=============》");
//
SFTPUtil sf=new SFTPUtil();
sf.connect();
System.out.println();
// sf.uploudFileToSftp(destFtp, "D:\\com-jk-api-service-bizaccount-1.0.0.jar", "com-jk-api-service-bizaccount-1.0.0.jar");
//
// System.out.println("end=============》");
//
//sf.uploudFileToSftp("测试.txt", "测试.txt");
}
/***
*
* @方法描述:将本地文件上传到ftp
* @author liufeng
* @param localFileName 比如 测试.txt
* @param remoteFileName 比如 测试.txt
* @2017年11月1日
*/
public String uploudFileToSftp(String localFileName, String remoteFileName,String destFilePath) {
String flag="1";
ChannelSftp sftp = null;
FileInputStream in = null;
Session sshSession = null;
SysConfigService cfgService = (SysConfigService) SpringContextUtil.getBean("com.wyl.modules.platform.sysconfig.service.SysConfigService");
String destFileLocalPath=ResourceBundle.getBundle("sftpsystem",new Locale("zh", "CN"))
.getString("local_temp_file_path");
String FtpSet = cfgService.queryValueByCode(SYSDICTPARA.BIZ_SFTP);
String[] arr=FtpSet.split(",");
int destFtpPort =Integer.parseInt(arr[1]);
String destFtpIp = arr[0];
String destUserName = arr[2];
String destPassWord = arr[3];
/*String destFilePath=ResourceBundle.getBundle("sftpsystem",new Locale("zh", "CN"))
.getString("sftp_acc_49_chargeplan_path"); */
try {
// 创建sftp连接
JSch jsch = new JSch();
jsch.getSession(destUserName, destFtpIp, destFtpPort);
sshSession = jsch.getSession(destUserName, destFtpIp, destFtpPort);
sshSession.setPassword(destPassWord);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
try {
//如果目录不存在,则自动创建
mkdir(destFilePath, sftp);
sftp.cd(destFilePath);
logger.info(destFileLocalPath+File.separator+localFileName);
in = new FileInputStream(destFileLocalPath+File.separator+localFileName);
sftp.put(in, remoteFileName);
logger.info("文件转送成功"+localFileName);
flag="0";
Thread.sleep(1000);
//删除本地目录下的全部文件
logger.info("上传完成后,我们要删除本地目录下的全部临时文件....");
SFTPUtil.fileDelete(new File(destFileLocalPath+File.separator+localFileName));
}catch(FileNotFoundException e){
logger.info("文件不存在"+localFileName);
}catch(Exception e){
logger.error("文件转送失败"+localFileName,e);
}
} catch (Exception e) {
logger.error("sftp连接失败",e);
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
logger.error("资源关闭出错",e);
}
try {
if (sftp != null) {
sftp.disconnect();
}
} catch (Exception e) {
logger.error("资源关闭出错",e);
}
try {
if (sshSession != null) {
System.out.println("close sshSession success");
sshSession.disconnect();
}
} catch (Exception e) {
logger.error("sshSession关闭出错",e);
}
}
return flag;
}
/***
* @方法描述:上传完文件以后,删除本地该文件
* @author liufeng
* @param File f f必须是文件
* @2017年11月8日
*/
public static void fileDelete(File f){
if(f.isFile()){
f.delete();
}
}
/**
* 对账文件从本方sftp转送到对方sftp
*/
public String sftpToSftp(Map<String,String> srcFtp, Map<String,String> destFtp, String fileName) {
String flag="1";
ChannelSftp srcsftp = null;
ChannelSftp destsftp = null;
InputStream in = null;
Session destSshSession=null;
Session srcSshSession=null;
String srcFtpIp=srcFtp.get("srcFtpIp");
int srcFtpPort=Integer.parseInt(srcFtp.get("srcFtpPort"));
String srcUserName=srcFtp.get("srcUserName");
String srcPassWord=srcFtp.get("srcPassWord");
String srcFilePath=srcFtp.get("srcFilePath");
String destFtpIp=destFtp.get("destFtpIp");
int destFtpPort=Integer.parseInt(destFtp.get("destftpPort"));
String destUserName=destFtp.get("destUserName");
String destPassWord=destFtp.get("destPassWord");
String destFilePath=destFtp.get("destFilePath");
try {
// 创建目标端sftp连接
JSch destjsch = new JSch();
destjsch.getSession(destUserName, destFtpIp, destFtpPort);
destSshSession = destjsch.getSession(destUserName, destFtpIp, destFtpPort);
destSshSession.setPassword(destPassWord);
Properties destSshConfig = new Properties();
destSshConfig.put("StrictHostKeyChecking", "no");
destSshSession.setConfig(destSshConfig);
destSshSession.connect();
Channel destChannel = destSshSession.openChannel("sftp");
destChannel.connect();
destsftp = (ChannelSftp) destChannel;
// 创建源端sftp连接
JSch srcjsch = new JSch();
destjsch.getSession(srcUserName, srcFtpIp, srcFtpPort);
srcSshSession = srcjsch.getSession(srcUserName, srcFtpIp, srcFtpPort);
srcSshSession.setPassword(srcPassWord);
Properties srcSshConfig = new Properties();
srcSshConfig.put("StrictHostKeyChecking", "no");
srcSshSession.setConfig(srcSshConfig);
srcSshSession.connect();
Channel srcChannel = srcSshSession.openChannel("sftp");
srcChannel.connect();
srcsftp = (ChannelSftp) destChannel;
try {
destsftp.cd(destFilePath);
srcsftp.cd(srcFilePath);
in = srcsftp.get(fileName);
if(in==null){
logger.info("文件不存在"+fileName);
}else{
destsftp.put(in, fileName);
logger.info("文件转送成功"+fileName);
flag="0";
}
}catch(Exception e){
logger.error("文件转送失败"+fileName,e);
}
} catch (Exception e) {
logger.error("sftp连接失败",e);
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
logger.error("资源关闭出错",e);
}
try {
if (destsftp != null) {
destsftp.disconnect();
}
} catch (Exception e) {
logger.error("资源关闭出错",e);
}
try {
if (srcsftp != null) {
srcsftp.disconnect();
}
} catch (Exception e) {
logger.error("资源关闭出错",e);
}
try {
if (destSshSession != null) {
System.out.println("close destSshSession success");
destSshSession.disconnect();
}
} catch (Exception e) {
logger.error("sshSession关闭出错",e);
}
try {
if (srcSshSession != null) {
System.out.println("close srcSshSession success");
srcSshSession.disconnect();
}
} catch (Exception e) {
logger.error("sshSession关闭出错",e);
}
}
return flag;
}
/**
* Sftp文件下载到本地
* @param srcFtp ftp配置
* @param filePathName 本地文件绝对路径
* @param fileName 文件名称
*/
public String downloadFromSftp(Map<String, String> srcFtp,String tempPath, String fileName) {
String flag="0";
ChannelSftp sftp = null;
InputStream in = null;
FileOutputStream out=null;
Session sshSession=null;
try {
String srcFtpIp=srcFtp.get("ip");
int srcFtpPort=Integer.parseInt(srcFtp.get("port"));
String srcUserName=srcFtp.get("userName");
String srcPassWord=srcFtp.get("passWord");
String srcFilePath=srcFtp.get("filePath");
// 创建sftp连接
JSch jsch = new JSch();
jsch.getSession(srcUserName, srcFtpIp, srcFtpPort);
sshSession = jsch.getSession(srcUserName, srcFtpIp, srcFtpPort);
sshSession.setPassword(srcPassWord);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
logger.info("********ftp目录-"+srcFilePath);
logger.info("********本地临时目录-"+tempPath);
logger.info("********文件名称-"+fileName);
try {
sftp.cd(srcFilePath);
try{
in = sftp.get(fileName);
}catch(Exception e){
logger.info("-----------对账文件还未上传-"+fileName);
}
if(in==null){
flag="1";
}else{
out = new FileOutputStream(tempPath+fileName);
int byteCount = -1;
byte[] buffer = new byte[1024 * 1024];
while ((byteCount = in.read(buffer)) != -1) {
out.write(buffer, 0, byteCount);
}
out.flush();
logger.info("----------文件下载成功"+tempPath+fileName);
}
}catch(Exception e){
logger.error("----------文件下载失败"+srcFilePath+"/"+fileName,e);
flag="2";
}
} catch (Exception e) {
logger.error("sftp连接失败",e);
flag="3";
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
logger.error("资源关闭出错",e);
}
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
logger.error("资源关闭出错",e);
}
try {
if (sftp != null) {
System.out.println("closed sftp success");
sftp.disconnect();
}
} catch (Exception e) {
logger.error("sftp关闭出错",e);
}
try {
if (sshSession != null) {
System.out.println("closed sshSession success");
sshSession.disconnect();
}
} catch (Exception e) {
logger.error("sshSession关闭出错",e);
}
}
return flag;
}
/**
*
* @方法描述 在服务器上创建相应文件夹
* @auther liufeng
* @param destFilePath 目录格式 /xx[/xx/xx ...]
* 2017年11月7日
*/
private void mkdir(String destFilePath, ChannelSftp sftp) throws Exception{
if (StringUtils.isBlank(destFilePath) || destFilePath.indexOf("/") != 0)
return ;
String dirs = destFilePath.substring(1);
String[] dirArr = dirs.split("/");
String base = "";
for (String d : dirArr) {
base += "/" + d;
if (dirExist(base + "/", sftp)) {
continue;
} else {
sftp.mkdir(base + "/");
}
}
}
/**
*
* @方法描述 判断文件夹是否存在
* @auther liufeng
* 2017年11月7日
*/
private boolean dirExist(String dir, ChannelSftp sftp) {
try {
Vector<?> vector = sftp.ls(dir);
if (null == vector)
return false;
else
return true;
} catch (SftpException e) {
return false;
}
}
/**
* Sftp文件下载到本地
* @param srcFtp ftp配置
* @param filePathName 本地文件绝对路径
*
*/
public String downloadFromSftp(String tempPath,String srcFilePath) {
String flag="0";
ChannelSftp sftp = null;
InputStream in = null;
FileOutputStream out=null;
Session sshSession=null;
try {
String srcFtpIp=SFTPDTO.IP;
int srcFtpPort=SFTPDTO.PROT;
String srcUserName=SFTPDTO.USERNAME;
String srcPassWord=SFTPDTO.PASSWORD;
// 创建sftp连接
JSch jsch = new JSch();
jsch.getSession(srcUserName, srcFtpIp, srcFtpPort);
sshSession = jsch.getSession(srcUserName, srcFtpIp, srcFtpPort);
sshSession.setPassword(srcPassWord);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
logger.info("********ftp目录-"+srcFilePath);
logger.info("********本地临时目录-"+tempPath);
//logger.info("********文件名称-"+fileName);
try {
sftp.cd(srcFilePath);//进入指定目录
java.util.Vector fileList= sftp.ls(srcFilePath);//得到指定目录下的文件列表
for(int i=0;i<fileList.size();i++) {
LsEntry lsEntry = (LsEntry) fileList.get(i);
String newFileName = srcFilePath;
String fileName = lsEntry.getFilename();
File downfile=new File(tempPath+fileName+".read");//如果文件已下载过直接下一个,因文件已重命名,加了一个.read
if(downfile.exists()){
continue;
}
//如果是.ok文件或者目录级别的文件直接跳过,循环下一条记录
if (".".equals(fileName) || "..".equals(fileName) || fileName.indexOf("ok") > 0) {
logger.info("目录级别和.ok文件不下载");
continue;
}
//程序走到这里一定是不带.ok的文件。 判断.ok的文件是否存在,如果不存在则继续循环下一条记录
boolean isOkFile=isExistOkFile(sftp,srcFilePath,fileName+".ok");
logger.info(fileName+".ok文件是否存在:"+isOkFile);
if(!isOkFile){
return fileName+".ok文件不存在";
}
//不等于.ok的文件。如果
logger.info("文件目录:"+srcFilePath);
in = sftp.get(fileName);
if(in==null){
flag="1";
}else{
File file=new File(tempPath);
if(!file.exists()){//文件不存在创建文件
file.mkdir();
logger.info("文件不存在创建文件"+tempPath);
}
out = new FileOutputStream(tempPath+fileName);
int byteCount = -1;
byte[] buffer = new byte[1024 * 1024];
while ((byteCount = in.read(buffer)) != -1) {
out.write(buffer, 0, byteCount);
}
out.flush();
logger.info("----------文件下载成功"+tempPath+fileName);
}
}
}catch(Exception e){
logger.error("----------文件下载失败"+srcFilePath+"/",e);
flag="2";
}
} catch (Exception e) {
logger.error("sftp连接失败",e);
flag="3";
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
logger.error("资源关闭出错",e);
}
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
logger.error("资源关闭出错",e);
}
try {
if (sftp != null) {
logger.info("closed sftp success");
sftp.disconnect();
}
} catch (Exception e) {
logger.error("sftp关闭出错",e);
}
try {
if (sshSession != null) {
System.out.println("closed sshSession success");
sshSession.disconnect();
}
} catch (Exception e) {
logger.error("sshSession关闭出错",e);
}
}
return flag;
}
public boolean isExistOkFile( ChannelSftp sftp, String srcFilePath,String okFileName)throws Exception{
java.util.Vector fileList= sftp.ls(srcFilePath);
for(int i=0;i<fileList.size();i++){
LsEntry lsEntry= (LsEntry)fileList.get(i);
String fileName=lsEntry.getFilename();
if(okFileName.equals(fileName)){
return true;
}
}
return false;
}
/**
* @方法描述 连接SFTP服务器
* @Auther zhangjilong
* @Date 2017年12月28日
*/
public void connect() {
try {
//SysConfigService cfgService = (SysConfigService) SpringContextUtil.getBean("com.wyl.modules.platform.sysconfig.service.SysConfigService");
String FtpSet = "192.168.232.145,ftpuser,12345678";//cfgService.queryValueByCode(SYSDICTPARA.BIZ_SFTP);
String[] arr = FtpSet.split(",");
int port = 22;//Integer.parseInt(arr[1]);
String host = arr[0];
String username = arr[1];
String password = arr[2];
JSch jsch = new JSch();
jsch.getSession(username, host, port);
sshSession = jsch.getSession(username, host, port);
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
logger.info("Session 连接成功.");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
logger.info("Opening Channel.");
sftp = (ChannelSftp) channel;
logger.info("Connected to " + host + ".");
} catch (Exception e) {
logger.error("SFTP连接出错--connect()", e);
}
}
/**
* @方法描述 关闭连接
* @Auther zhangjilong
* @Date 2017年12月28日
*/
public void disconnectSFTP() {
if (this.sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
logger.info("sftp已成功关闭!");
}
}
if (this.sshSession != null) {
if (sshSession.isConnected()) {
sshSession.disconnect();
logger.info("sshSession已成功关闭!");
}
}
}
/**
* @方法描述 从SFTP下载文件到本地
* @Param remotPath:远程下载目录,以路径符号结束
* @Param remoteFileName:下载文件名 带后缀名
* @Param localPath:本地保存目录,以路径符号结束
* @Param localFileName:保存文件名 带后缀名
* @Auther zhangjilong
* @Date 2017年12月28日
*/
public boolean downloadFile(String remotePath, String remoteFileName,
String localPath, String localFileName) {
FileOutputStream fieloutput = null;
try {
connect();
// sftp.cd(remotePath);
File file = new File(localPath + localFileName);
//本地目录不存在自动创建
File fileParent = file.getParentFile();
if(!fileParent.exists()){
//设置写权限, linux环境
fileParent.setWritable(true, false);
fileParent.mkdirs();
}
fieloutput = new FileOutputStream(file);
sftp.get(remotePath + remoteFileName, fieloutput);
logger.info("从SFTP上下载文件:" + remoteFileName + " 成功.");
return true;
} catch (Exception e) {
logger.error("SFTP文件下载失败--downloadFile", e);
} finally {
this.disconnectSFTP();
if (null != fieloutput) {
try {
fieloutput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
/**
* 将人事侠Sftp文件下载到本地
* @param srcFtp ftp配置
* @param filePathName 本地文件绝对路径
*
*/
public String downloadFromJFXSftp(String tempPath,String srcFilePath) {
String flag="0";
ChannelSftp sftp = null;
InputStream in = null;
FileOutputStream out=null;
Session sshSession=null;
try {
SysConfigService cfgService = (SysConfigService) SpringContextUtil.getBean("com.wyl.modules.platform.sysconfig.service.SysConfigService");
String FtpSet =""; //cfgService.queryValueByCode(SYSDICTPARA.BIZ_SFTP_JFX);
String[] arr = FtpSet.split(",");
int srcFtpPort = Integer.parseInt(arr[1]);
String srcFtpIp = arr[0];
String srcUserName = arr[2];
String srcPassWord = arr[3];
// 创建sftp连接
JSch jsch = new JSch();
jsch.getSession(srcUserName, srcFtpIp, srcFtpPort);
sshSession = jsch.getSession(srcUserName, srcFtpIp, srcFtpPort);
sshSession.setPassword(srcPassWord);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
logger.info("********ftp目录-"+srcFilePath);
logger.info("********本地临时目录-"+tempPath);
//logger.info("********文件名称-"+fileName);
try {
sftp.cd(srcFilePath);//进入指定目录
java.util.Vector fileList= sftp.ls(srcFilePath);//得到指定目录下的文件列表
for(int i=0;i<fileList.size();i++) {
LsEntry lsEntry = (LsEntry) fileList.get(i);
String newFileName = srcFilePath;
String fileName = lsEntry.getFilename();
File downfile=new File(tempPath+fileName+".read");//如果文件已下载过直接下一个,因文件已重命名,加了一个.read
if(downfile.exists()){
continue;
}
//如果是.ok文件或者目录级别的文件直接跳过,循环下一条记录
if (".".equals(fileName) || "..".equals(fileName) || fileName.indexOf("ok") > 0) {
logger.info("目录级别和.ok文件不下载");
continue;
}
//程序走到这里一定是不带.ok的文件。 判断.ok的文件是否存在,如果不存在则继续循环下一条记录
boolean isOkFile=isExistOkFile(sftp,srcFilePath,fileName+".ok");
logger.info(fileName+".ok文件是否存在:"+isOkFile);
if(!isOkFile){
return fileName+".ok文件不存在";
}
//不等于.ok的文件。如果
logger.info("文件目录:"+srcFilePath);
in = sftp.get(fileName);
if(in==null){
flag="1";
}else{
File file=new File(tempPath);
if(!file.exists()){//文件不存在创建文件
file.mkdir();
logger.info("文件不存在创建文件"+tempPath);
}
out = new FileOutputStream(tempPath+fileName);
int byteCount = -1;
byte[] buffer = new byte[1024 * 1024];
while ((byteCount = in.read(buffer)) != -1) {
out.write(buffer, 0, byteCount);
}
out.flush();
logger.info("----------文件下载成功"+tempPath+fileName);
}
}
}catch(Exception e){
logger.error("----------文件下载失败"+srcFilePath+"/",e);
flag="2";
}
} catch (Exception e) {
logger.error("sftp连接失败",e);
flag="3";
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
logger.error("资源关闭出错",e);
}
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
logger.error("资源关闭出错",e);
}
try {
if (sftp != null) {
logger.info("closed sftp success");
sftp.disconnect();
}
} catch (Exception e) {
logger.error("sftp关闭出错",e);
}
try {
if (sshSession != null) {
System.out.println("closed sshSession success");
sshSession.disconnect();
}
} catch (Exception e) {
logger.error("sshSession关闭出错",e);
}
}
return flag;
}
}