Java 执行 SFTP 文件上传和下载
✅ 推荐:使用 sshj(客户端连接 SSH)https://blog.csdn.net/z1353095373/article/details/149959817
适合:远程登录服务器、执行命令、上传/下载文件等。
❌ 不推荐:使用 jsch(客户端连接 SSH)
不支持 ssh 新版本算法。
package com.example.job.ssh.sftp.ga;import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;import java.util.Map;
import java.util.Properties;/*** JSch - Java实现的SFTP(文件上传下载) - lihewei - 博客园* https://www.cnblogs.com/lihw/p/17168705.html#%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD-get--%E6%96%B9%E6%B3%95*/
@Slf4j
public class SFTPChannel {private Session session = null;private Channel channel = null;private static final int TIMEOUT = 60000;/*** 登录sftp*/public ChannelSftp getChannel(Map<String, String> sftpDetails) throws JSchException {String ftpHost = sftpDetails.get(SFTPConstants.SFTP_REQ_HOST);int ftpPort = Integer.parseInt(sftpDetails.get(SFTPConstants.SFTP_DEFAULT_PORT));String ftpUserName = sftpDetails.get(SFTPConstants.SFTP_REQ_USERNAME);String ftpPassword = sftpDetails.get(SFTPConstants.SFTP_REQ_PASSWORD);// 创建JSch对象JSch jsch = new JSch();// 根据用户名,主机ip,端口获取一个Session对象session = jsch.getSession(ftpUserName, ftpHost, ftpPort);log.info("Session created.");if (ftpPassword != null) {session.setPassword(ftpPassword);}Properties config = new Properties();config.put("StrictHostKeyChecking", "no");session.setConfig(config); // 为Session对象设置propertiessession.setTimeout(TIMEOUT); // 设置timeout时间session.connect(); // 通过Session建立链接log.info("Session connected.");log.info("Opening Channel.");channel = session.openChannel("sftp"); // 打开SFTP通道channel.connect(); // 建立SFTP通道的连接log.info("Connected successfully to ftpHost = " + ftpHost + ",as ftpUserName = " + ftpUserName+ ", returning: " + channel);return (ChannelSftp) channel;}/*** 退出sftp*/public void closeChannel() {if (channel != null) {channel.disconnect();}if (session != null) {session.disconnect();}}}
package com.example.job.ssh.sftp.ga;public class SFTPConstants {public static final String SFTP_REQ_HOST = "xx.xx.xx.xxx";public static final String SFTP_DEFAULT_PORT = "22";public static final String SFTP_REQ_USERNAME = "root";public static final String SFTP_REQ_PASSWORD = "xxx";
}
package com.example.job.ssh.sftp.ga;import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jcraft.jsch.ChannelSftp;
import lombok.extern.slf4j.Slf4j;import java.util.HashMap;
import java.util.Map;@Slf4j
public class SFTPGetTest {/*** 服务器上传名和原名 对应关系*/private final static JSONObject FILE_REAL_NAME = JSONUtil.readJSONObject(FileUtil.file("sftp/ga/filenamemap.json"), CharsetUtil.CHARSET_UTF_8);/*** 服务器文件上传路径*/private final static String STORAGE_FILE_PATH = "/home/docker-compose/ga-api/data/attachment/6514/yuqingmanage/submit/";public static void main(String[] args) throws Exception {// 新建临时路径String bashPath = "D:/data/ga/" + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_MS_PATTERN);String dstPath = bashPath + "/files/";String dstZipPath = bashPath + "/zip/ga_file.zip";FileUtil.mkdir(dstPath);// 设置主机ip,端口,用户名,密码Map<String, String> sftpDetails = new HashMap<>();sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, SFTPConstants.SFTP_REQ_HOST);sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME, SFTPConstants.SFTP_REQ_USERNAME);sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD, SFTPConstants.SFTP_REQ_PASSWORD);sftpDetails.put(SFTPConstants.SFTP_DEFAULT_PORT, SFTPConstants.SFTP_DEFAULT_PORT);// SFTPSFTPChannel channel = new SFTPChannel();ChannelSftp chSftp = channel.getChannel(sftpDetails);String src = null;try {int i = 1;for (Map.Entry<String, Object> map : FILE_REAL_NAME) {String storageFileName = map.getKey();String originalFileName = (String) map.getValue();// 服务器路径src = STORAGE_FILE_PATH + storageFileName;// 处理下载文件名为原名,重命名:增加序号,解决文件名重复问题String oriFileMainName = FileUtil.mainName(originalFileName);String oriFileExtName = FileUtil.extName(originalFileName);String oriFileNewName = i + "-" + oriFileMainName + "." + oriFileExtName;log.info("文件服务器存储名:{},对应原名:{}", storageFileName, oriFileNewName);// 下载路径String dst = dstPath + oriFileNewName;// 下载文件chSftp.get(src, dst);log.info("文件:{},下载完成", src);i++;}} catch (Exception e) {log.error("文件下载异常:" + src, e);} finally {chSftp.quit();channel.closeChannel();}// 压缩ZipUtil.zip(dstPath, dstZipPath);log.info("文件压缩完成:{}", dstZipPath);}}