当前位置: 首页 > news >正文

SpringBoot连接Sftp服务器实现文件上传/下载(亲测可用)

目录

一、先导入pom依赖

二、工具类完整代码 


一、先导入pom依赖

<dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.55</version>
</dependency>

二、工具类完整代码 

package com.example.excel.util;import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;
import java.util.Vector;/*** SFTP工具类* 功能:测试连接、下载文件、上传文件*/
public class SftpUtil {private static final Logger log = LoggerFactory.getLogger(SftpUtil.class);private final String host;private final int port;private final String username;private final String password;private Session session;private ChannelSftp channel;public SftpUtil(String host, int port, String username, String password) {this.host = host;this.port = port;this.username = username;this.password = password;}/*** 测试SFTP连接* @return true连接成功,false连接失败*/public boolean testConnection() {try {connect();return true;} catch (JSchException e) {log.error("SFTP连接测试失败: {}", e.getMessage());return false;} finally {disconnect();}}/*** 下载文件* @param remotePath 远程文件路径* @param localPath 本地保存路径* @return true下载成功,false下载失败*/public boolean downloadFile(String remotePath, String localPath) {try (OutputStream output = Files.newOutputStream(Paths.get(localPath))) {connect();channel.get(remotePath, output);log.info("文件下载成功: {} -> {}", remotePath, localPath);return true;} catch (JSchException | SftpException | IOException e) {log.error("文件下载失败: {}", e.getMessage());return false;} finally {disconnect();}}/*** 上传文件* @param localPath 本地文件路径* @param remotePath 远程保存路径* @return true上传成功,false上传失败*/public boolean uploadFile(String localPath, String remotePath) {try (InputStream input = Files.newInputStream(Paths.get(localPath))) {connect();// 1. 提取远程目录路径String remoteDir = extractDirectoryPath(remotePath);// 2. 确保目录存在(不存在则创建)ensureDirectoryExists(remoteDir);channel.put(input, remotePath);log.info("文件上传成功: {} -> {}", localPath, remotePath);return true;} catch (JSchException | SftpException | IOException e) {log.error("文件上传失败: {}", e.getMessage());return false;} finally {disconnect();}}/*** 检查远程文件是否存在* @param remotePath 远程文件路径* @return true存在,false不存在*/public boolean fileExists(String remotePath) {try {connect();channel.lstat(remotePath);return true;} catch (SftpException e) {if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {return false;}log.error("检查文件存在时出错: {}", e.getMessage());return false;} catch (JSchException e) {log.error("连接异常: {}", e.getMessage());return false;} finally {disconnect();}}/*** 创建SFTP连接*/private void connect() throws JSchException {if (channel != null && channel.isConnected()) {return;}JSch jsch = new JSch();session = jsch.getSession(username, host, port);session.setPassword(password);// 配置不检查主机密钥(生产环境应配置known_hosts)Properties config = new Properties();config.put("StrictHostKeyChecking", "no");session.setConfig(config);session.connect();Channel channel = session.openChannel("sftp");channel.connect();this.channel = (ChannelSftp) channel;}/*** 从文件路径中提取目录路径* @param filePath 完整文件路径* @return 目录路径*/private String extractDirectoryPath(String filePath) {int lastSlash = filePath.lastIndexOf('/');if (lastSlash <= 0) {return "/"; // 根目录}return filePath.substring(0, lastSlash);}/*** 确保远程目录存在(不存在则递归创建)* @param remoteDir 远程目录路径*/private void ensureDirectoryExists(String remoteDir) throws SftpException {try {// 尝试进入目录(存在则直接返回)channel.cd(remoteDir);} catch (SftpException e) {// 目录不存在,需要创建if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {// 递归创建父目录int lastSlash = remoteDir.lastIndexOf('/');if (lastSlash > 0) {String parentDir = remoteDir.substring(0, lastSlash);ensureDirectoryExists(parentDir);}// 创建当前目录channel.mkdir(remoteDir);channel.cd(remoteDir); // 进入新创建的目录log.debug("创建目录: {}", remoteDir);} else {throw e; // 其他异常重新抛出}}}/*** 断开SFTP连接*/private void disconnect() {if (channel != null) {channel.disconnect();channel = null;}if (session != null) {session.disconnect();session = null;}}// 使用示例public static void main(String[] args) {// 1. 创建SFTP工具实例SftpUtil sftp = new SftpUtil("10.10.10.10",2222,"username","password");// 2. 测试连接System.out.println("连接测试: " + (sftp.testConnection() ? "成功" : "失败"));// 3. 检查文件是否存在String remoteFile = "/remote/path/test.txt";System.out.println("文件存在检查: " + (sftp.fileExists(remoteFile) ? "存在" : "不存在"));// 4. 下载文件sftp.downloadFile("/upload/test/test.zip", "D:\\local.zip");// 5. 上传文件sftp.uploadFile("C:\\Users\\test\\Desktop\\log.log", "/upload/test/test.log");}
}

http://www.lryc.cn/news/600377.html

相关文章:

  • Linux选择题
  • 《从零开始学 JSSIP:JavaScript 实时通信开发实战》
  • Jmeter的元件使用介绍:(五)定时器详解
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现轮船检测识别(C#代码UI界面版)
  • PostGIS面试题及详细答案120道之 (011-020 )
  • 零基础学习性能测试第三章:jmeter构建性能业务场景
  • 论文阅读-RaftStereo
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-27,(知识点:信号完整性,信号反射,串扰,时延,抖动,衰减)
  • Qt 延时处理方法介绍
  • day 36打卡
  • 去中心化时代的通信革命:briefing与cpolar技术融合带来的安全范式革新
  • 明辨 JS 中 prototype 与 __proto__
  • 秋招Day19 - 分布式 - 限流
  • C++11 右值引用 Lambda 表达式
  • 基于深度学习的食管癌右喉返神经旁淋巴结预测系统研究
  • CSS3知识补充
  • git笔记(七)使用代理
  • 从一个“诡异“的C++程序理解状态机、防抖与系统交互
  • 外带服务的温度:藏在包装里的“生活共情力”
  • 从零开始的云计算生活——第三十六天,山雨欲来,Ansible入门
  • Java 注解(Annotation)详解:从基础到实战,彻底掌握元数据驱动开发
  • Containerd简介
  • C++ APM异步编程模式剖析
  • 【AcWing 830题解】单调栈
  • JVM 基础架构全解析:运行时数据区与核心组件
  • OpenCV学习探秘之二 :数字图像的矩阵原理,OpenCV图像类与常用函数接口说明,及其常见操作核心技术详解
  • kafka中生产者的数据分发策略
  • Scrapy分布式爬虫数据统计全栈方案:构建企业级监控分析系统
  • 从0到1学Pandas(七):Pandas 在机器学习中的应用
  • 详解力扣高频SQL50题之1193. 每月交易 I【简单】