首先,在yml文件中配置sftp连接信息以及文件目录
下面是本人写的sftp工具类,连接sftp服务的方法。
private static ChannelSftp sftp = null;
private static Session session = null;
/**
* 连接sftp服务器
*
* @param privateKey
* @return
*/
public static ChannelSftp sftpConnect(String host, int port, String username, String password, String privateKey) throws SftpException {
try {
JSch jsch = new JSch();
if (privateKey != null && !"".equals(privateKey)) {
jsch.addIdentity(privateKey);// 设置私钥
}
//用户名,主机,端口号
session = jsch.getSession(username, host, port);
//密码
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
// 设置timeout时间
session.setTimeout(30000);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
} catch (Exception e) {
log.error("连接sftp失败", e);
log.error("ip{},port{}", host, port);
throw new SftpException(500, "连接sftp失败", e);
}
return sftp;
}
连接成功后,读取sftp服务指定目录下的文件
public static String getFtpData(String ftpPath, String fileType, String taskDate) throws SftpException, IOException {
StringBuffer fileContent = new StringBuffer();
BufferedReader br = null;
//连接ftp
if (null == sftp) {
return "";
}
String dateStr = StringUtils.isNotBlank(taskDate) ? taskDate.replaceAll("-", "") : getYesterDayV2();
String directory = "/" + dateStr + "/";
String fileName = "";
try {
//下载文件
String rootDirectory = ftpPath.substring(ftpPath.lastIndexOf("/") + 1);
sftp.cd(rootDirectory + directory);
switch (fileType){
case "subject":
fileName = "ACS_SUBJECT_Q.dat" ;
break;
case "account":
fileName = "ACS_ACCOUNT_Q.dat" ;
break;
case "product":
fileName = "ACS_PRODUCT_Q.dat" ;
break;
}
br = new BufferedReader(new InputStreamReader(sftp.get(fileName), StandardCharsets.UTF_8));
//不读取第一行的数据
br.readLine();
String temp;
while ((temp = br.readLine()) != null) {
fileContent.append(temp + System.lineSeparator());
}
if (fileContent.length() > 0) {
fileContent.deleteCharAt(fileContent.length() - 1);
}
} catch (Exception e) {
log.error(fileName + "文件读取异常{}", e.getStackTrace().toString());
} finally {
br.close();
closeChannel();
}
return fileContent.toString();
}
关闭连接:
/**
* 关闭ftp连接
*/
public static void closeChannel() {
if (sftp != null) {
sftp.disconnect();
}
if (session != null) {
if (session.isConnected()) {
session.disconnect();
}
}
}
public static String getYesterDayV2() {
DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, -24);
String yesterdayDate = dateFormat.format(calendar.getTime());
System.out.println(yesterdayDate);
return yesterdayDate;
}
需要注意的是读取文件时,如果是root用户 ,可直接读取文件的全路径 ,譬如:
/home/exchange/app/blockchain/data/20221001/test.txt
br = new BufferedReader(new InputStreamReader(sftp.get(fileName), StandardCharsets.UTF_8));
不过一般都是指定用户登录的,即非root用户,此时就只能读取当前用户登录sfp根目录下的文件路径,比如用户登录sftp根目录是 /home/exchange/app/blockchain ,那么此时读取文件路径就是 /data/20221001/test.txt
当然,也可以先切换到指定文件目录下 data/20221001/ ,然后再读取test.txt文件名。