在对账文件下载等多个场景,需要连接远程服务sftp下载文件。
注意:文件传输后需要生成结尾文件,当读取时判断文件传输已完成。
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.49</version>
<scope>compile</scope>
</dependency>
package com.yuantiaokj.ftpmodule.util;
import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.IOException;
import java.util.Vector;
/**
* ************************************************************
* Copyright © 2020 远眺科技 Inc.All rights reserved. * **
* ************************************************************
*
* @program: module-lib
* @description: sftp工具方法
* @author: cnzz
* @create: 2020-08-08 15:23
* <p>
* 目录:
* 1、main 测试入口
* 2、sftpDown sftp下载
**/
@Slf4j
public class SftpUtil {
/**
* main 测试方法
*
* @param args
*/
public static void main(String[] args) throws IOException {
String host = "ip";
int port = 22;
String username = "paycentre";
String password = "paycentre";
String sftpSource = "/data/userhome/paycentre/test";
String localTarget = "d://test1";
sftpDown(new SftpInfo().setHost(host).setPort(port).setUsername(username).setPassword(password).setSftpSource(sftpSource).setLocalTarget(localTarget));
//生成结尾文件
String filePath = localTarget + File.separator +"end.txt";
File file = new File(filePath);
if (!file.exists()) {
file.createNewFile();
}
}
/**
* sftp下载
* cnzz 20200808
*
* @param sftpInfo sftp信息
*/
public static void sftpDown(SftpInfo sftpInfo) {
//1、建立sftp连接
ChannelSftp channelSftp = null;
try {
channelSftp = getChannelSftp(sftpInfo.getHost(), sftpInfo.getPort(), sftpInfo.getUsername(), sftpInfo.getPassword());
} catch (JSchException | SftpException e) {
e.printStackTrace();
throw new RuntimeException("sftp 连接建立失败|" + e.getMessage());
}
//目标地址不存在了创建
File targetFolder = new File(sftpInfo.getLocalTarget());
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
//2、文件传输
try {
folderDownload(channelSftp, sftpInfo.getSftpSource(), sftpInfo.getLocalTarget());
} catch (IOException | SftpException e) {
e.printStackTrace();
throw new RuntimeException("sftp 文件传输异常|" + e.getMessage());
}
//3、断开连接
disconnectChannelSftp(channelSftp);
}
/**
* 目录递归下载
* cnzz 20200808
*
* @param channelSftp sftp通道
* @param sftpSource sftp文件地址
* @param localTarget 本地地址
* @throws IOException IOException
*/
private static void folderDownload(ChannelSftp channelSftp, String sftpSource, String localTarget) throws IOException, SftpException {
//获取目录链接
Vector<ChannelSftp.LsEntry> fileAndFolderList = channelSftp.ls(sftpSource);
//比遍历LsEntry
for (ChannelSftp.LsEntry item : fileAndFolderList) {
if (!item.getAttrs().isDir()) {
//如果不是文件夹,文件
//判断文件不存在了新建
String filePath = localTarget + File.separator + item.getFilename();
File file = new File(filePath);
if (!file.exists()) {
file.createNewFile();
}
//文件传输
channelSftp.get(sftpSource + File.separator + item.getFilename(),
localTarget + File.separator + item.getFilename());
} else if (!(".".equals(item.getFilename()) || "..".equals(item.getFilename()))) {
//是文件夹,排除 . ..
//新建该文件夹
new File(localTarget + File.separator + item.getFilename()).mkdirs();
//文件夹递归
folderDownload(channelSftp, sftpSource + File.separator + item.getFilename(),
localTarget + File.separator + item.getFilename());
}
}
}
/**
* 建立ChannelSftp连接
* cnzz 20200808
*
* @param host ip
* @param port 端口
* @param username 用户
* @param password 密码
* @return ChannelSftp
*/
private static ChannelSftp getChannelSftp(String host, int port, String username, String password) throws JSchException, SftpException {
JSch jsch = new JSch();
Session session = jsch.getSession(username, host, port);
session.setPassword(password);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
// Create SFTP Session
session.connect();
// Open SFTP Channel
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp channelSftp = (ChannelSftp) channel;
// Change Directory on SFTP Server
channelSftp.cd(File.separator);
return channelSftp;
}
/**
* 断开连接
* cnzz 20200808
*
* @param channelSftp
*/
private static void disconnectChannelSftp(ChannelSftp channelSftp) {
if (channelSftp != null) {
channelSftp.disconnect();
}
}
}
import lombok.Data;
import lombok.experimental.Accessors;
/**
* ************************************************************
* Copyright © 2020 远眺科技 Inc.All rights reserved. * **
* ************************************************************
*
* @program: module-lib
* @description: sftp信息
* @author: cnzz
* @create: 2020-08-08 15:55
**/
@Data
@Accessors(chain = true)
public class SftpInfo {
private String host;
private Integer port;
private String username;
private String password;
private String sftpSource;
private String localTarget;
}