入职第一周,分配到一个需求,需要到sftp服务器上下载投诉信息的csv文件,然后解析csv文件,把投诉信息保存到clickhouse数据库。记录一下连接sftp服务的过程。
sftp简介
FTP(File Transfer Protocol):文件传输协议,是用于在网络上进行文件传输的一套标准协议。
与ftp协议不同,SFTP(SSH File Transfer Protocol):SSH文件传输协议(安全文件传送协议),是一种加密的文件传输协议。连接sftp服务需要提供用户名和密码。
可以使用FileZilla来连接远程服务,查看文件
打开软件->文件->新站点,然后依次填写主机IP地址,端口为22,用户名,密码即可登录成功。
代码示例
接下来编写代码实现文件下载,流程如下
- 获取ChannelSftp连接
- 将指定文件下载到本地
添加依赖
<!--sftp核心依赖包-->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
private static final String IP = "";
private static final Integer PORT = 22;
private static final String USERNAME = "";
private static final String PASSWORD = "";
private static final String REMOTEFILE_PATH = "/home/app/mastercom/tousu/";
private static final String LOCALFILE_PATH = "F:\\testDir\\";
先指定远程的文件目录,本地的文件目录
JSch jsch = new JSch();
try {
Session session = jsch.getSession(USERNAME, IP, PORT);
session.setPassword(PASSWORD);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
channelSftp.connect();
//这里面可以写操作文件的逻辑
channelSftp.disconnect();
session.disconnect();
} catch (Exception e) {
e.printStackTrace();
logger.info("从sftp服务下载文件出现异常,e:{}",e);
}
logger.info("从sftp服务下载文件完成,下载的文件路径,fileNameList:{}", fileNameList);
在我的业务中要选取特定的文件,将文件名符合条件的文件下载。
先根据指定的的时间格式获取当前时间的字符串表达式,比如”20230728_1630“
//获取当前时间的向下取整半小时的匹配时间
Date currentTime = new Date();
String roundedTime = roundDownToHalfHour(currentTime);
private String roundDownToHalfHour(Date currentTime) {
long timeMillis = currentTime.getTime();
// 向下取整到半小时的时间戳
long timeRounded = timeMillis - (timeMillis % (30 * 60 * 1000));
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmm");
return sdf.format(new Date(timeRounded));
}
获取远程目录下的所有文件,过滤掉需要下载的文件,注意文件夹也要排除掉
// 获取远程文件夹下的所有文件
Vector<ChannelSftp.LsEntry> fileList = channelSftp.ls(REMOTEFILE_PATH);
for (ChannelSftp.LsEntry entry : fileList) {
if (!entry.getAttrs().isDir()) {
String filename = entry.getFilename();
// 如果文件名匹配上,则下载到本地
if (filename.contains(roundedTime)) {
String remoteFileName = REMOTEFILE_PATH + filename;
// 指定本地文件保存路径
String localFileName = LOCALFILE_PATH + filename;
File localFile = new File(localFileName);
FileOutputStream output = new FileOutputStream(localFile);
channelSftp.get(remoteFileName, output);
fileNameList.add(localFileName);
}
}
}
将文件的路径和文件名保存到list返回,方便之后同步文件到数据库