1.ftp和sftp主要区别
FTP是一种文件传输协议,一般是为了方便数据共享的。包括一个FTP服务器和多个FTP客户端。FTP客户端通过FTP协议在服务器上下载资源。而SFTP协议是在FTP的基础上对数据进行加密,使得传输的数据相对来说更安全。但是这种安全是以牺牲效率为代价的,也就是说SFTP的传输效率比FTP要低(不过现实使用当中,没有发现多大差别)。个人肤浅的认为就是:一;FTP要安装,SFTP不要安装。二;SFTP更安全,但更安全带来副作用就是的效率比FTP要低些。
2.引入pom文件
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
3. 配置application.properties文件
sftp.client.username="ftp";
sftp.client.password="****"
sftp.client.host="127.0.0.0"
sftp.client.port="22"
4.配置sftp连接类SftpConnect
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
@Component
public class SftpConnect {
private static Logger logger = LoggerFactory.getLogger(SftpConnect.class);
private long sleepTime = 60000;
private Session sshSession;
private ChannelSftp sftp;
// FTP 登录用户名
@Value("${sftp.client.username}")
private String userName;
// FTP 登录密码
@Value("${sftp.client.password}")
private String pwd;
// FTP 服务器地址IP地址
@Value("${sftp.client.host}")
private String host;
// FTP 端口
@Value("${sftp.client.port}")
private int port;
/**
* 连接sftp
*
* @return
* @throws Exception
*/
public ChannelSftp connect() throws Exception {
try {
JSch jsch = new JSch();
logger.info("sftp host: " + host + "; userName:" + userName);
sshSession = jsch.getSession(userName, host, port);
logger.debug("Session 已建立.");
if (pwd != null) {
sshSession.setPassword(pwd);
}
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
logger.debug("Session 已连接.");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
logger.info("连接到SFTP成功。host: " + host);
} catch (Exception e) {
logger.error("连接sftp失败!");
Thread.sleep(sleepTime);
logger.info("重新连接....");
connect();
}
return sftp;
}
/**
* 关闭连接 server
*/
public void disconnect(ChannelSftp sftp) {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
sshSession.disconnect();
logger.info("sftp连接关闭成功!" + sftp);
} else if (sftp.isClosed()) {
logger.warn("sftp 已经关闭,不需要重复关闭!" + sftp);
}
}
}
}
5.创建sftp SftpCommonService类包括创建文件上传文件
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpException;
@Component
public class SftpCommonService {
private static Logger logger = LoggerFactory.getLogger(SftpCommonService.class);
// 文件标志位
private String rootdirectory="/root";
private String logo="d";
private static final String RECEIVESYSTEMCODE = "5678";
private static final String SENDSYSTEMCODE = "1234";
private static final String SSID = "adc";
private static final String UNDERLINE = "_";
private static final String SUFFIX = ".txt";
/**
* 上传文件到固定文件下
*
* @param sftp
* @param targetPath
* @param in
* @param fileName
* @return
* @throws Exception
*/
public String uploadFile(ChannelSftp sftp, String targetPath, InputStream in, String fileName, String provinceId,
String businessType, String SN) throws Exception {
try {
boolean dirFlag = true;
int index = targetPath.lastIndexOf("/");
String fileDir = targetPath.substring(0, index);
if (fileName == null) {
fileName = fileName(provinceId, businessType, SN);
}
//判断文件夹路径是否存在不存在创建文件夹
if (!isDirExist(sftp, targetPath)) {
dirFlag = createDirs(fileDir, sftp);
} else {
sftp.cd(targetPath);
}
if (!dirFlag) {
logger.error("Remote path error. path:{}", targetPath);
throw new Exception("Upload File failure");
}
//上传文件到sftp服务器
sftp.put(in, fileName, ChannelSftp.RESUME);
} catch (Exception e) {
logger.error("Upload file failure. TargetPath: {}", targetPath);
throw new Exception("Upload File failure");
}
return fileName;
}
/**
* 创建目录
*
* @param dirPath
* @param sftp
* @return
*/
private boolean createDirs(String dirPath, ChannelSftp sftp) {
if (dirPath != null && !dirPath.isEmpty() && sftp != null) {
String[] dirs = Arrays.stream(dirPath.split("/")).filter(StringUtils::isNotBlank).toArray(String[]::new);
try {
sftp.cd(rootdirectory);
} catch (SftpException e2) {
logger.info("Change directory {}");
}
for (String dir : dirs) {
try {
sftp.cd(dir);
logger.info("Change directory {}", dir);
} catch (Exception e) {
try {
sftp.mkdir(dir);
logger.info("Create directory {}", dir);
} catch (SftpException e1) {
logger.error("Create directory failure, directory:{}", dir);
}
try {
sftp.cd(dir);
logger.info("Change directory {}", dir);
} catch (SftpException e1) {
logger.error("Change directory failure, directory:{}", dir);
}
}
}
return true;
}
return false;
}
/**
* 判断目录是否存在
*
* @param sftp
* @param directory
* @return
*/
public boolean isDirExist(ChannelSftp sftp, String directory) {
try {
Vector<?> vector = sftp.ls(directory);
if (null == vector) {
return false;
} else {
return true;
}
} catch (Exception e) {
return false;
}
}
/**
* 创建文件名
*
* @return
*/
public String fileName(String provinceId, String businessType, String SN) {
// 文件产生时间
Date date = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String ymdhms = df.format(date);
StringBuffer buffer = new StringBuffer();
buffer.append(ymdhms);
buffer.append(UNDERLINE);
buffer.append(RECEIVESYSTEMCODE);
buffer.append(UNDERLINE);
buffer.append(logo);
buffer.append(UNDERLINE);
buffer.append(SSID);
buffer.append(UNDERLINE);
buffer.append(businessType);
String provinceIdZero = String.format("%03d", Long.parseLong(provinceId));
buffer.append(provinceIdZero);
buffer.append(UNDERLINE);
buffer.append(SENDSYSTEMCODE);
buffer.append(UNDERLINE);
buffer.append(SN);
buffer.append(SUFFIX);
return buffer.toString();
}
/**
* 删除文件
*
* @param targetPath
* @return
* @throws Exception
*/
public boolean deleteFile(ChannelSftp sftp, String targetPath) throws Exception {
try {
sftp.rm(targetPath);
return true;
} catch (Exception e) {
logger.error("Delete file failure. TargetPath: {}", targetPath);
throw new Exception("Delete File failure");
}
}
/**
* 删除文件
*
* @param pathname
* @return
* @throws IOException
*/
public boolean deleteFile(File file) {
boolean result = false;
if (file.exists()) {
if (file.delete()) {
result = true;
}
}
return result;
}
/**
* 删除文件夹
*
* @param sftp
* @param targetPath
* @return
* @throws Exception
*/
public boolean deleteFolder(ChannelSftp sftp, String targetPath) throws Exception {
try {
sftp.rmdir(targetPath);
return true;
} catch (Exception e) {
logger.error("Delete folder failure. TargetPath: {}", targetPath);
throw new Exception("Delete File failure");
}
}
/**
* 处理文件名绝对路径
*
* @param filePath
* @param fileName
* @return P:/temp/1.txt 或者 p:/temp/x
*/
public String pasreFilePath(String filePath, String fileName) {
StringBuffer sb = new StringBuffer();
if (filePath.endsWith("/") || filePath.endsWith("\\")) {
sb.append(filePath).append(fileName);
} else {
sb.append(filePath.replaceAll("\\\\", "/")).append("/").append(fileName);
}
return sb.toString();
}
/**
* 获取偏移量日期 - 数字格式
*
* @param offsetDay
* 0,当天;正数,当天之后;负数,当天之前offsetDay天
* @return yyyyMMdd
*/
public String getOffsetDay(int offsetDay) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, offsetDay);
return new SimpleDateFormat("yyyyMMdd").format(cal.getTime());
}
/**
* 获取今天日期 - 数字格式
*
* @return yyyyMMdd
*/
public String getCurrentday() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 0);
return new SimpleDateFormat("yyyyMMddHH").format(cal.getTime());
}
public String getNowStr() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 0);
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(cal.getTime());
}
}
6.创建一个定时任务进行测试
import java.util.ArrayList;
import java.util.List;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@EnableScheduling // 通过@EnableScheduling注解开启对计划任务的支持
public class TaskSchedule {
private static Logger logger = LoggerFactory.getLogger(TaskSchedule.class);
@Autowired
private SftpCommonService sftpCommon;
private String backupRecordpath="/root";
@Scheduled(cron = "0 0/1 * * * ?")
public String CreateCallRecordsFile() {
ChannelSftp sftp = null;
InputStream inputStream = null;
try {
sftp = connect.connect();
String fileValues="1236666";
String provinceId=""10;
String businessType="1";
String SN="dd";
inputStream = new ByteArrayInputStream(fileValues.getBytes());
String fileNames = sftpCommon.uploadFile(sftp, backupRecordpath, inputStream, null, provinceId,
businessType, SN);
} catch (Exception e) {
logger.error("文件生成异常:" + e);
return "4444";
} finally {
if (inputStream != null) {
inputStream.close();
}
connect.disconnect(sftp);
}
return "0000";
}
}