java如何上传文件到sftp服务器

 更新时间:2026年04月21日 09:25:04   作者:@猪大肠  
本文主要讲述了如何使用JSch库将数据文件上传到SFTP服务器,并分享了过程中遇到的一些坑,例如目录创建、文件删除等问题,以及如何使用SFTP通道执行命令、文件上传等操作,通过本文,读者可以了解SFTP上传文件的基本步骤和注意事项,同时也提供了一些解决方法

java上传文件到sftp服务器

最近公司有个数据对接需求,合作方那边是使用我们这边的系统进行出单的,数据首先也是在我们这边。

后面他们自己开发了业务系统,需要我们这边定时把每天的数据传送到那边去。

他们那边开发部门要求我们这边,按一定的格式导出加签加密的数据文件到他们的sftp服务器上面去。

sftp代码之前同事有写过类似的代码,就把他的给我啦,既然有了代码,当然要消化成自己的知识啦!

这个过程中也遇到一些坑,就是我们上传到sftp目录的时候,文件一多我们就得隔开文件夹,一般都是按年月隔开的,但是sftp切换目录后,如果目录不存在,我们就新建目录,这样的逻辑是没毛病,但是它没办法一次建多级目录,比如/home 下面可以建/home/2022/ 没办法建/home/2022/03(会报异常),所以这个的话我们还得用循环来做。

代码

先给大家看下代码:

    String userName = "";//账号
    String password = ""; //密码
    String host = "";  //ip
    int port=8889; //端口号
    String sftpUrl = "/application/data";   //上传到sftp服务器 路径
    String publicUrl = "E://";     //要上传的文件
    String yyyy = DateUtils.formatDate(new Date(), "yyyy");
    String mm = DateUtils.formatDate(new Date(), "MM");
    String uploadUrl = sftpUrl + "/" + yyyy + "/" + mm;
        //存储目录地址
    List dirs = new ArrayList();
    dirs.add(0, sftpUrl + "/" + yyyy + "/");
    dirs.add(1, sftpUrl + "/" + yyyy + "/" + mm + "/");
        
            try {
                //1.获取会话
                JSch jSch = new JSch();
                Session session = jSch.getSession(userName, host, port);
                session.setPassword(password);
                Properties properties = new Properties();
                properties.put("StrictHostKeyChecking", "no");
                session.setConfig(properties);
                session.connect();
                //2.获取上传的管道
                Channel channel = session.openChannel("sftp");
                channel.connect();
                sftp = (ChannelSftp) channel;
                if (!(uploadUrl == null || uploadUrl.trim().length() == 0)) {
                    for (int index = 0; index < dirs.size(); index++) {
                        //目录不存在,新建目录
                        try {
                            sftp.cd(uploadUrl);//进入指定目录
                            break;
                        } catch (SftpException e1) {

                            try {
                                sftp.cd(dirs.get(index).toString());
                            } catch (SftpException e2) {
                                try {
                                    sftp.mkdir(dirs.get(index).toString());
                                    sftp.cd(dirs.get(index).toString());
                                } catch (SftpException e3) {
                                    logger.error("SFTP切换目录出错!", e3);
                                }
                            }
                        }
                    }
                }

                //读取源文件流(客户端文件)
                InputStream client_fileInput = new FileInputStream(publicUrl );

                sftp.put(client_fileInput, “上传后的文件名”);
                //传送到服务端
                //5.关闭
                sftp.disconnect();
                client_fileInput.close();
                channel.disconnect();
                session.disconnect();
                logger.info("sftp传输成功");
            } catch (Exception e) {
                logger.info("sftp传输失败: " + e.toString());
                e.printStackTrace();
            }

一般上传完文件后,需要删除本地的文件以免占用空间

    /**
     * 迭代删除文件夹
     * @param dirPath 文件夹路径
     */
    public static void deleteDir(String dirPath) {
        File file = new File(dirPath);
        if(!file.exists()){
            return;
        }
        if(file.isFile())
        {
            file.delete();
        }else {
            File[] files = file.listFiles();
            if(files == null) {
                file.delete();
            }else {
                for (int i = 0; i < files.length; i++) {
                    deleteDir(files[i].getAbsolutePath());
                }
                file.delete();
            }
        }
    }

这里我遇到个坑,就是你们发现文件夹或者文件没删除或者没删除干净,就要检查一下流有没有关闭,传递流的时候最好不要直接 xxx方法(new FileInputStream),用下面这种方式比较好,好排查问题,哈哈。

FileInputStream file=new FileInputStream(“”); xxx方法(file);file.close();

sftp连接过程

2.1、JSch简介

JSch库可以实现Java连接Linux服务器并操作命令、文件等,支持常用的各种授权模式。

3.1、JSch建立会话连接

从JSch对象中获取Session,用于连接,并设置连接信息,账号、密码、服务器地址、端口号。

3.2 、设置连接的参数配置

StrictHostKeyChecking=no 最不安全的级别,当然也没有那么多烦人的提示了,相对安全的内网测试时建议使用。如果连接server的key在本地不存在,那么就自动添加到文件中(默认是known_hosts),并且给出一个警告。
StrictHostKeyChecking=ask 默认的级别。如果连接和key不匹配,给出提示,并拒绝登录。
StrictHostKeyChecking=yes 最安全的级别,如果连接与key不匹配,就拒绝连接,不会提示详细信息。

3.3、获取文件上传的通道

通过以上的步骤,我们与sftp服务器建立了连接后,我们需要获取文件的传输通道Channel,并指定为sftp服务,随便进行connect()连接。

3.3、常用命令

获取了sftp通道,我们可以类似在linux下简单做一些shell指令操作:

  • mkdir()方法 创建目录,只允许创建一级目录
  • cd()方法 切换目录
  • put()方法 上传文件
  • rm()方法 删除文件

还有很多,大家可以直接看对象的对应方法就知道了,方法命名跟我们平时用的linux命令差不多。

用完一定要记得关闭各种连接跟流呀!!!!!!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • idea中的update project按钮使用

    idea中的update project按钮使用

    这篇文章主要介绍了idea中的update project按钮使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • SpringBoot配置MySQL5.7与MySQL8.0的异同点详解

    SpringBoot配置MySQL5.7与MySQL8.0的异同点详解

    MySQL 是 Java 开发中最常用的数据库之一,而 Spring Boot 提供了便捷的配置方式,随着 MySQL 8.0 的普及,许多开发者需要从 MySQL 5.7 升级到 8.0,在实际开发中,二者的配置方式既有相似之处,也有一些需要特别注意的不同点,所以本文给大家详细介绍了它们的异同点
    2024-12-12
  • SpringBoot集成AOP的代码示例

    SpringBoot集成AOP的代码示例

    AOP是一种编程范式,它旨在将横切关注点(cross-cutting concerns)从应用程序的业务逻辑中分离出来,横切关注点是那些在多个模块中重复出现的功能,如日志记录、性能监控、事务管理、安全控制等,本文介绍了Spring Boot如何集成AOP,需要的朋友可以参考下
    2024-09-09
  • Spring基于注解管理bean实现方式讲解

    Spring基于注解管理bean实现方式讲解

    很多时候我们需要根据不同的条件在容器中加载不同的Bean,或者根据不同的条件来选择是否在容器中加载某个Bean,这就是Bean的加载控制,一般我们可以通过编程式或注解式两种不同的方式来完成Bean的管理
    2023-01-01
  • Mybatis如何自动生成数据库表的实体类

    Mybatis如何自动生成数据库表的实体类

    这篇文章主要介绍了Mybatis自动生成数据库表的实体类的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 在springboot中使用p6spy方式

    在springboot中使用p6spy方式

    这篇文章主要介绍了在springboot中使用p6spy方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • java.lang.ArrayIndexOutOfBoundsException数组越界异常问题解决

    java.lang.ArrayIndexOutOfBoundsException数组越界异常问题解决

    这篇文章主要给大家介绍了关于java.lang.ArrayIndexOutOfBoundsException数组越界异常问题解决的相关资料,数组越界访问是一个非常严重的问题,文中通过图文将解决的办法介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • springmvc配置线程池Executor做多线程并发操作的代码实例

    springmvc配置线程池Executor做多线程并发操作的代码实例

    今天小编就为大家分享一篇关于springmvc配置线程池Executor做多线程并发操作的代码实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Mybatis generator修改Mapper.java文件实现详解

    Mybatis generator修改Mapper.java文件实现详解

    这篇文章主要为大家介绍了Mybatis generator修改Mapper.java文件实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Java 自定义线程池和线程总数控制操作

    Java 自定义线程池和线程总数控制操作

    这篇文章主要介绍了Java 自定义线程池和线程总数控制操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02

最新评论