Java整合Jsch实现SFTP连接对服务器文件增删改查操作

我们在开发中,有时候需要操作服务器上的文件,Spring Boot可以使用JSch库来连接SFTP并进行操作服务器上的文件读写。

创建一个SFTP连接需要以下步骤:

  • 1.创建JSch对象
  • 2.使用JSch对象创建Session对象
  • 3.使用Session对象连接到SFTP服务器
  • 4.打开SFTP通道
  • 5.使用SFTP通道打开SFTP连接
1.添加依赖

pom.xml文件中添加以下依赖:

<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>
2.创建SftpConfig配置类
import lombok.Getter;
import lombok.Setter;

/**
 * <p>
 * SFTP连接参数配置类
 * description: 如果后续只需要操作一台固定不变的服务器,可以从配置文件中读取
 * </p>
 *
 * @author 
 * @Url 
 * @since 
 */
@Setter
@Getter
public class SftpConfig {
    /**
     * SFTP服务器地址
     */
    private String host;
    /**
     * SFTP服务器端口
     */
    private int port;
    /**
     * SFTP服务器用户名
     */
    private String username;
    /**
     * SFTP服务器密码 如果不使用密码方式则留空
     */
    private String password;
    /**
     * 密钥文件路径,如果不使用密钥连接则留空
     */
    private String privateKeyPath;

    /**
     * 密钥文件口令,如果不使用密钥连接则留空
     */
    private String passphrase;
    /**
     * 连接SFTP服务器超时时间 2秒
     */
    private Integer sessionConnectTimeoutTime = 2000;
    /**
     * 打开通道超时时间 2秒
     */
    private Integer channelSftpConnectTimeoutTime = 2000;

    /**
     * 密码方式连接方法
     *
     * @param host           SFTP服务器地址
     * @param port           SFTP服务器端口
     * @param username       SFTP服务器用户名
     * @param password       SFTP服务器密码 如果不使用连接则留空
     */
    public SftpConfig(String host, int port, String username, String password) {
        this.host = host;
        this.port = port;
        this.username = username;
        this.password = password;
    }

    /**
     * 秘钥方式连接方法
     *
     * @param host           SFTP服务器地址
     * @param port           SFTP服务器端口
     * @param username       SFTP服务器用户名
     * @param privateKeyPath 密钥文件路径,如果不使用密钥连接则留空
     * @param passphrase     密钥文件口令,如果不使用密钥连接则留空
     */
    public SftpConfig(String host, int port, String username,String privateKeyPath, String passphrase) {
        this.host = host;
        this.port = port;
        this.username = username;
        this.privateKeyPath = privateKeyPath;
        this.passphrase = passphrase;
    }

}
3.创建SFTP操作工具类
import com.jcraft.jsch.*;
import com.risk.riskControl.config.SftpConfig;

import java.io.*;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * SFTP操作工具类
 * </p>
 *
 * @author 
 * @Url 
 * @since 
 */
public class SftpService {
    /**
     * SFTP连接参数
     */
    private SftpConfig config;
    /**
     * JSch对象,用于创建SFTP连接
     */
    private JSch jsch;
    /**
     * Session对象,用于连接到SFTP服务器
     */
    private Session session;
    /**
     * SFTP通道,用于打开SFTP连接
     */
    private ChannelSftp channelSftp;

    /**
     * 构造函数,初始化SFTP连接参数
     *
     * @param config SFTP连接参数
     */
    public SftpService(SftpConfig config) {
        this.config = config;
        // 创建JSch对象
        this.jsch = new JSch();
    }

    /**
     * 连接到SFTP服务器
     *
     * @throws JSchException
     */
    public void connect() throws JSchException {
        try {
            // 创建Session对象
            session = jsch.getSession(config.getUsername(), config.getHost(), config.getPort());
            if (config.getPassword() != null) {
                // 使用密码连接
                session.setPassword(config.getPassword());
            } else if (config.getPrivateKeyPath() != null) {
                // 使用私钥连接
                jsch.addIdentity(config.getPrivateKeyPath(), config.getPassphrase());
            }
            // 不进行主机密钥检查
            session.setConfig("StrictHostKeyChecking", "no");
            // 设置SFTP连接超时时间
            session.connect(config.getSessionConnectTimeoutTime());
            // 打开SFTP通道
            channelSftp = (ChannelSftp) session.openChannel("sftp");
            // 设置通道连接超时时间
            channelSftp.connect(config.getChannelSftpConnectTimeoutTime());
        } catch (JSchException e) {
            // 连接异常处理
            throw new JSchException("Failed to connect to SFTP server: " + e.getMessage());
        }
    }


    /**
     * 断开SFTP连接
     */
    public void disconnect() {
        if (channelSftp != null) {
            // 断开SFTP连接
            channelSftp.disconnect();
        }
        if (session != null) {
            // 断开Session连接
            session.disconnect();
        }
    }

    /**
     * 上传文件到SFTP服务器
     *
     * @param localFilePath  本地文件路径
     * @param remoteFilePath SFTP服务器文件路径
     * @throws SftpException
     * @throws FileNotFoundException
     */
    public void uploadFile(String localFilePath, String remoteFilePath) throws SftpException, IOException {
        // 使用try-with-resources语句,可以自动关闭资源
        try (InputStream inputStream = new FileInputStream(localFilePath)) {
            // 上传文件到SFTP服务器
            channelSftp.put(inputStream, remoteFilePath);
        }
    }

    /**
     * 从SFTP服务器下载文件
     *
     * @param remoteFilePath SFTP服务器文件路径
     * @param localFilePath  本地文件路径
     * @throws SftpException
     * @throws FileNotFoundException
     */
    public void downloadFile(String remoteFilePath, String localFilePath) throws SftpException, IOException {
        // 使用try-with-resources语句,可以自动关闭资源
        try (OutputStream outputStream = new FileOutputStream(localFilePath)) {
            // 从SFTP服务器下载文件
            channelSftp.get(remoteFilePath, outputStream);
        }
    }

    /**
     * 删除SFTP服务器上的文件
     *
     * @param remoteFilePath SFTP服务器文件路径
     * @throws SftpException
     */
    public void deleteFile(String remoteFilePath) throws SftpException {
        // 删除SFTP服务器上的文件
        channelSftp.rm(remoteFilePath);
    }

    /**
     * 列出SFTP服务器上的文件
     * 使用这段代码会有什么问题,是否还可以优化
     *
     * @param remoteDirectory SFTP服务器目录
     * @return 文件列表
     * @throws SftpException
     */
    public List<String> listFiles(String remoteDirectory) throws SftpException {
        List<String> fileList;
        // 列出SFTP服务器上的文件
        try (Stream<ChannelSftp.LsEntry> stream = channelSftp.ls(remoteDirectory).stream()) {
            fileList = stream
                    // 过滤掉目录
                    .filter(entry -> !entry.getAttrs().isDir())
                    // 获取文件名
                    .map(ChannelSftp.LsEntry::getFilename)
                    // 将文件名收集到List中
                    .collect(Collectors.toList());
        }
        return fileList;
    }

}
4.创建SftpTest测试类
import com.risk.riskControl.config.SftpConfig;

import java.util.List;

/**
 * /**
 * <p>
 * SftpTest测试类
 * </p>
 *
 * @author 
 * @Url 
 * @since 
 */
public class SftpTest {

    /**
     * 测试SFTP连接及文件上传、下载、删除、列出操作
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // 构建SFTP参数,如果是参数固定一个不变改为用配置文件读取
        SftpConfig config = new SftpConfig("sftp.songzixian.com", 22, "szxBlog", "12345678");
        // 秘钥方式连接
        //SftpConfig config = new SftpConfig("sftp.songzixian.com", 22, "root", "D:\\id_rsa_szx_blog.ppk","blog123");
        // 连接到SFTP服务器
        SftpService sftpService = new SftpService(config);
        sftpService.connect();
        // 本地路径
        String localFilePath = "";
        // 服务器路径
        String remoteFilePath = "";
        // 上传文件使用
        // 本地文件路径
        localFilePath = "D:\\code\\a.txt";
        // SFTP服务器文件路径
        remoteFilePath = "/usr/local/sftp-test/a.txt";
        // 上传文件到SFTP服务器
        sftpService.uploadFile(localFilePath, remoteFilePath);

        // 下载文件使用
        // SFTP服务器文件路径
        remoteFilePath = "/usr/local/sftp-test/a.txt";
        // 本地文件路径
        localFilePath = "D:\\code\\aaaa.txt";
        // 从SFTP服务器下载文件
        sftpService.downloadFile(remoteFilePath, localFilePath);
        // 删除文件使用
        remoteFilePath = "/usr/local/sftp-test/a.txt";
        // 删除SFTP服务器上的文件
        sftpService.deleteFile(remoteFilePath);

        // 列出文件
        // SFTP服务器目录
        String remoteDirectory = "/usr/local/sftp-test/";
        // 列出SFTP服务器上的文件
        List<String> files = sftpService.listFiles(remoteDirectory);
        for (String file : files) {
            System.out.println(file);
        }

        System.out.println("操作成功");
        // 断开SFTP连接
        sftpService.disconnect();
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/764651.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flink实现准确和高效流处理的关键问题

时间相关: Watermark 水位线 水位线是插入到数据流中的一个标记,可以认为是一个特殊的数据。水位线主要的内容是一个时间戳,用来表示当前事件时间的进展。水位线是基于数据的时间戳生成的。水位线的时间戳必须单调递增,以确保任务的事件时间时钟一直向前推进,进展。水位线…

linux 离线安装docker

测试服务器&#xff1a;银河麒麟V10 x86_64 注意&#xff1a;推荐使用国内的镜像站下载&#xff0c;因为官网不挂梯子无法访问&#xff0c;我用的是清华大学开源软件镜像站 一、下载离线包&#xff1a; 官网下载docker离线包 下载地址&#xff1a;https://download.docker.c…

C# 计算椭圆上任意一点坐标

已知圆心坐标 &#xff08;x0&#xff0c;y0&#xff09;&#xff0c;横轴 A&#xff08;长半轴&#xff09;&#xff0c;竖轴 B&#xff08;短半轴&#xff09;&#xff0c;角度 a&#xff0c;则圆边上点&#xff08;x&#xff0c;y&#xff09;的坐标为&#xff1a; 方法一 …

金蝶云星空字段之间连续触发值更新

文章目录 金蝶云星空字段之间连续触发值更新场景说明具体需求&#xff1a;解决方案 金蝶云星空字段之间连续触发值更新 场景说明 字段A配置了字段B的计算公式&#xff0c;字段B配置了自动C的计算公式&#xff0c;修改A的时候&#xff0c;触发了B的重算&#xff0c;但是C触发不…

BIOS设置与系统分区

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 目录 一BIOS 1破解密码的前提 2B…

机器学习实战20-利用AnoSVGD算法探索多指标的异常检测的应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下机器学习实战20-利用AnoSVGD算法探索多指标的异常检测的应用。SVGD(Stein Variational Gradient Descent)是一种通用的变分推断算法&#xff0c;它是优化中梯度下降的自然对应物。SVGD通过应用一种功能性梯度下降来…

游戏AI的创造思路-技术基础-tanh函数详解

又来搞事情&#xff0c;总想着把sigmoid函数替换成其他函数作为激活函数&#xff0c;或者找到更合适某一段训练的函数&#xff0c;所以今天来聊聊tanh函数&#xff08;谁让咱当年差点去了数学系&#xff0c;结果还是在数学系转过去计算机的&#xff09; 目录 3.9. tanh函数详解…

让采购和工程师们既爱又恨的任务——BOM

在项目研发与生产过程中&#xff0c;有一个常常让采购经理和工程师们既爱又恨的任务&#xff0c;那就是整理BBOMB。BOM作为连接设计与制造的桥梁&#xff0c;其重要性不言而喻&#xff0c;它详细列出了产品构成所需的所有零部件、材料及其规格、数量&#xff0c;是成本估算、采…

如何选择品牌推广公司?哪家好?收费标准及评价!

不管是什么品牌&#xff0c;推广对公司的成败起了很关键的作用。然而&#xff0c;面对市面上琳琅满目的品牌推广公司&#xff0c;如何选择一家既熟悉又靠谱的公司&#xff0c;成为许多企业主面临的难题。 作为一家手工酸奶品牌的创始人&#xff0c;目前全国也复制了100多家门店…

超简洁Django个人博客系统(适合初学者)

一、环境介绍 Django4.2.13Markdown3.3.4PyMySQL1.1.1Python3.8PyCharm 2023.1.2 (Professional Edition) 二、功能简介 用户登录 通过在pycharm终端执行以下命令创建超级管理员。python manage.py create createsuperuser 创建完成后再通过新建的超级管理员账号进行登录 …

Java的日期类常用方法

Java_Date 第一代日期类 获取当前时间 Date date new Date(); System.out.printf("当前时间" date); 格式化时间信息 SimpleDateFormat simpleDateFormat new SimpleDateFormat("yyyy-mm-dd hh:mm:ss E); System.out.printf("格式化后时间" si…

【Arduino】小飞鱼通达二开实验ESP32使用激光传感器(图文)

激光在我们的生活中应用很多&#xff0c;比如激光雷达、激光焊接、激光笔等等&#xff0c;今天我们来实验一下这个激光传感器模块。 这个模块的使用非常的简单&#xff0c;模块一共有3个针脚&#xff0c;正负极针脚和一个信号输入S针脚&#xff0c;当给到S针脚一个高电平时即可…

动手RAG: ocr调研

对于rag应用来说&#xff0c;文档是第一步&#xff0c;对于部分扫描件的文件来讲&#xff0c;主要就需要OCR. OCR tesseractppocrmmocr OCR包含几类&#xff0c; 自然场景中的文字识别&#xff0c;文档中的文字识别pipeline: 文本检测&#xff0c;文本识别&#xff0c;文…

武汉星起航:无锡跨境电商加速“出海”,物流升级助品牌全球布局

随着全球化的不断深入&#xff0c;跨境电商作为数字外贸的新业态&#xff0c;正逐渐成为无锡企业拓展海外市场的重要渠道。武汉星起航关注到&#xff0c;近年来&#xff0c;无锡市通过积极推进国际物流枢纽建设&#xff0c;完善海外仓布局&#xff0c;以及各特色产业带的积极参…

19184 传球游戏

这是一个经典的动态规划问题&#xff0c;我们可以定义一个二维数组dp[i][j]&#xff0c;其中i表示传球的次数&#xff0c;j表示球当前在哪个同学手里。我们需要找到的是dp[m][1]&#xff0c;即球传了m次后又回到1号同学手里的方法数。 我们可以从1次开始&#xff0c;逐次计算每…

老师怎样一键发布期末考试成绩?

期末考试的钟声一响&#xff0c;老师们便开始了紧张的阅卷工作。成绩出来后&#xff0c;他们又面临着一项繁琐的任务——将成绩单逐一私信给每位学生的家长。这不仅耗费了大量时间&#xff0c;也让老师们在繁忙的期末工作中倍感压力。期末老师的工作已经够多够繁琐&#xff0c;…

10款优秀的企业防泄密软件推荐 (干货必看)

在当今日益数字化的商业环境中&#xff0c;企业数据的安全性和保密性显得尤为重要。随着网络攻击和数据泄露事件的频发&#xff0c;越来越多的企业开始关注并投入资源于防泄密软件的使用。本文旨在为读者推荐10款优秀的企业防泄密软件&#xff0c;帮助企业在保护敏感信息方面做…

LabVIEW风机跑合监控系统

开发了一种基于LabVIEW的风机跑合监控系统&#xff0c;提高风机测试的效率和安全性。系统通过自动控制风机的启停、实时监控电流和功率数据&#xff0c;并具有过流保护功能&#xff0c;有效减少了人工操作和安全隐患&#xff0c;提升了工业设备测试的自动化和智能化水平。 项目…

轻松创建对象——简单工厂模式(Python实现)

1. 引言 大家好&#xff0c;又见面了&#xff01;今天我们要聊的是设计模式中的“万能钥匙”——简单工厂模式。想象一下&#xff0c;如果每次你都得亲自动手创建各种对象&#xff0c;不仅累得像个陀螺&#xff0c;还可能搞得一团糟。别怕&#xff0c;简单工厂模式来拯救你&am…