java 使用sftp从远程服务器上传下载删除文件

2023-10-26

前言

有时候我们需要让从代码里远程连接服务器进行文件上传、下载、判断文件路径是否存在、创建文件夹等操作。

这时候就用到了sftp。常见的三个库是:JSch、SSHJ 和 Apache Commons VFS它们都能实现远程连接服务器。

本文主要讲解利用JSch远程连接服务器。

一、所需依赖

maven如下:

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

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>

二、工具类

SftpUtil 工具类如下:


 
 import com.jcraft.jsch.*;
 import org.apache.commons.io.IOUtils;

 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.Charset;
 import java.util.Properties;

public class SftpUtil {
    private static JSch jsch;
    private static Session session = null;
    private static Channel channel = null;
    private static ChannelSftp channelSftp = null;

    //服务器用户名
    private String ftpUserName;

    //服务器密码
    private String ftpPassword;

    //服务器ip
    private String ftpHost;

    //服务器端口
    private String ftpPort;

    public SftpUtil() {
    }

    public SftpUtil(String ftpUserName, String ftpPassword, String ftpHost, String ftpPort) {
        this.ftpUserName = ftpUserName;
        this.ftpPassword = ftpPassword;
        this.ftpHost = ftpHost;
        this.ftpPort = ftpPort;
    }

    /**
     * 开启连接
     */
    public ChannelSftp connect() {
        jsch = new JSch();
        try {
            // 根据用户名、主机ip、端口号获取一个Session对象
            session = jsch.getSession(ftpUserName, ftpHost, Integer.valueOf(ftpPort));
            // 设置密码
            session.setPassword(ftpPassword);
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            // 为Session对象设置properties
            session.setConfig(config);
            // 设置连接超时为5秒
            session.setTimeout(100 * 50);
            // 通过Session建立连接
            session.connect();
            // 打开SFTP通道
            channel = session.openChannel("sftp");
            // 建立SFTP通道的连接
            channel.connect();
            channelSftp = (ChannelSftp) channel;
        } catch (JSchException e) {
            e.printStackTrace();
        }
        return channelSftp;
    }

    /**
     * 关闭连接
     */
    public void close() {
        if (channel != null) {
            channel.disconnect();
        }
        if (session != null) {
            session.disconnect();
        }
    }

    /**
     * 判断文件夹路径是否存在
     *
     * @param directory 文件夹路径,如:/root/test/saveFile/
     */
    public boolean isDirExist(String directory) {
        directory = null != directory && directory.endsWith("/") ? directory : directory + "/";
        boolean dirExist = false;
        try {
            SftpATTRS sftpATTRS = channelSftp.lstat(directory);
            dirExist = sftpATTRS.isDir();
        } catch (Exception e) {
            if (e.getMessage().equalsIgnoreCase("no such file")) {
                dirExist = false;
            }
        }
        return dirExist;
    }

    /**
     * 创建一个文件夹(若整个路径都不存在会依次创建,若该路径已经存在则不会创建)
     *
     * @param createpath 要创建的文件夹路径,如:/root/test/saveFile/
     * @throws SftpException
     */
    public void createDir(String createpath) {
        createpath = null != createpath && createpath.endsWith("/") ? createpath : createpath + "/";
        if (!isDirExist(createpath)) {
            StringBuilder builder = new StringBuilder("/");
            String pathArry[] = createpath.split("/");
            for (String dir : pathArry) {
                if (!dir.equals("")) {
                    builder.append(dir);
                    builder.append("/");
                    try {
                        String path = builder.toString();
                        if (!isDirExist(path)) {
                            // 建立目录
                            channelSftp.mkdir(path);
                        }
                    } catch (SftpException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 删除文件
     *
     * @param deleteFile 要删除的文件路径,如:/root/test/saveFile/mylog.log
     */
    public void deleteFile(String deleteFile) {
        try {
            channelSftp.rm(deleteFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件上传
     *
     * @param fileStram 文件输入流
     * @param upToPath  要上传到的文件夹路径
     * @param fileName  上传后的文件名
     */
    public void uploadFile(InputStream fileStram, String upToPath, String fileName) {
        upToPath = null != upToPath && upToPath.endsWith("/") ? upToPath : upToPath + "/";
        try {
            channelSftp.put(fileStram, upToPath + fileName);
        } catch (SftpException e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件下载
     *
     * @param downlownPath 要下载的文件的所在文件夹路径
     * @param fileName     文件名
     * @return download  返回下载的文件流
     */
    public InputStream downloadFile(String downlownPath, String fileName) {
        downlownPath = null != downlownPath && downlownPath.endsWith("/") ? downlownPath : downlownPath + "/";
        InputStream download = null;
        try {
            download = channelSftp.get(downlownPath + fileName);
        } catch (SftpException e) {
            e.printStackTrace();
        }
        return download;
    }


    /**
     * 执行linux命令
     *
     * @param order 要执行的命令,(如,打印指定目录下的文件信息: ls -a /usr/local/kkFileView/kkFileView-4.0.0/bin/)
     * @return result  执行后返回的结果
     */
    public String excutOrder(String order) {
        String result = "";
        try {
            ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
            channelExec.setCommand(order);
            channelExec.setErrStream(System.err);
            channelExec.connect();
            InputStream in = channelExec.getInputStream();
            result = IOUtils.toString(in, Charset.defaultCharset());
        } catch (JSchException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

}

如果你使用 springboot,可修改上面代码,使用户名、密码、服务器ip、端口从 yaml 或 properties 配置文件直接读取:

    @Value("${c.test.uploadFile.username:root}")
    private String ftpUserName;//用户名

    @Value("${c.test.uploadFile.password:123546:}")
    private String ftpPassword;//密码

    @Value("${c.test.uploadFile.host:127.0.0.7}")
    private String ftpHost;//服务器ip

    @Value("${c.test.uploadFile.port:22}")
    private String ftpPort;//端口
    

三、测试

1.判断指定目录是否存在

public static void main(String[] args) throws IOException {
		//开启连接
        SftpUtil sftpUtil = new SftpUtil("root", "46sdffhg", "127.0.0.1", "22");
        sftpUtil.connect();
        //判断目录是否存在
        boolean dirBoolean = sftpUtil.isDirExist("/usr/local/aaa/");
        //关闭连接
        sftpUtil.close();
}

2.创建一个文件夹

public static void main(String[] args) throws IOException {
		//开启连接
        SftpUtil sftpUtil = new SftpUtil("root", "46sdffhg", "127.0.0.1", "22");
        sftpUtil.connect();
        //创建一个文件夹
        sftpUtil.createDir("/usr/local/aaa/bbb/");
        //关闭连接
        sftpUtil.close();
}

3.删除指定文件

public static void main(String[] args) throws IOException {
		//开启连接
        SftpUtil sftpUtil = new SftpUtil("root", "46sdffhg", "127.0.0.1", "22");
        sftpUtil.connect();
        //删除指定文件
        sftpUtil.deleteFile("/usr/local/aaa/install.txt");
        //关闭连接
        sftpUtil.close();
}

4.把文件上传到服务器上

public static void main(String[] args) throws IOException {
		//开启连接
        SftpUtil sftpUtil = new SftpUtil("root", "46sdffhg", "127.0.0.1", "22");
        sftpUtil.connect();
        //把本地的文件上传到服务器上
        FileInputStream in = new FileInputStream(new File("D:\\GoogleDown\\myvideo.mp4"));
        sftpUtil.uploadFile(in,"/usr/local/aaa/","myvideo.mp4");
        in.close();
        //关闭连接
        sftpUtil.close();
}

5.从服务器上下载文件

public static void main(String[] args) throws IOException {
		//开启连接
        SftpUtil sftpUtil = new SftpUtil("root", "46sdffhg", "127.0.0.1", "22");
        sftpUtil.connect();
        //从服务器下载文件
        InputStream download = sftpUtil.downloadFile("/usr/local/aaa/", "myvideo.mp4");
        //把文件保存到本地
        File file = new File("D:\\myvideo.mp4");
        FileUtils.copyInputStreamToFile(download, file);
        download.close();
        //关闭连接
        sftpUtil.close();
}

6.执行Linux命令

(1) 调用 ls 命令打印指定目录下有哪些文件,然后返回结果

public static void main(String[] args) throws IOException {
		//开启连接
        SftpUtil sftpUtil = new SftpUtil("root", "46sdffhg", "127.0.0.1", "22");
        sftpUtil.connect();
        //打印/usr/local/aaa/目录下的所有文件信息
        String result = sftpUtil.excutOrder("ls -a -l /usr/local/aaa/");
        System.out.println(result);
        //关闭连接
        sftpUtil.close();
}

(2) 调用Linux命令执行curl,然后返回结果

public static void main(String[] args) throws IOException {
		//开启连接
        SftpUtil sftpUtil = new SftpUtil("root", "46sdffhg", "127.0.0.1", "22");
        sftpUtil.connect();
        //执行curl 命令
        String result = sftpUtil.excutOrder("curl --location --request POST 'https://www.baidu.com'");
        System.out.println(result);
        //关闭连接
        sftpUtil.close();
}

参考
java连接sftp工具类

SringBoot中MultipartFile上传文件

上传sftp,创建20171024目录,判断目录是否存在,复制文件,判断文件字符集

Java JSch示例在SSH Unix上运行shell命令

Java中com.jcraft.jsch.ChannelSftp讲解

Java实现sftp及远程执行命令

Java Code Examples for com.jcraft.jsch.ChannelSftp.put()

Java Code Examples for com.jcraft.jsch.Channel.getOutputStream()

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java 使用sftp从远程服务器上传下载删除文件 的相关文章

  • 使用 Tabula 通过 Python 读取 pdf 时出现 Java 错误

    我已经安装了 tabula 库 用于使用 python 将 pdf 读取到 pandas 数据框中 但是当我运行代码时 import tabula df tabula read pdf sample1 pdf pages 1 我得到了例外
  • Java Logger 未记录到 Netbeans 中的输出

    我正在 Netbeans 中使用 Maven 启动一个 Java 项目 我编写了一些代码来使用 Logger 类进行日志记录 但是 日志记录似乎不起作用 在程序开始时 我运行 Logger getLogger ProjectMainClas
  • eclipse行号状态行贡献项是如何实现的?

    我需要更新状态行编辑器特定的信息 我已经有了自己的实现 但我想看看 eclipse 贡献项是如何实现的 它显示状态行中的行号 列位置 谁能指点一下 哪里可以找到源代码 提前致谢 亚历克斯 G 我一直在研究它 它非常复杂 我不确定我是否了解完
  • 什么是抽象类? [复制]

    这个问题在这里已经有答案了 当我了解抽象类时 我说 WT H 问题 创建一个无法实例化的类有什么意义呢 为什么有人想要这样的课程 什么情况下需要抽象类 如果你明白我的意思 最常见的是用作基类或接口 某些语言有单独的interface构建 有
  • Jframe 内有 2 个 Jdialogs 的 setModal 问题

    当我设置第一个选项时 我遇到了问题JDialog模态 第二个非模态 这是我正在尝试实现的功能 单击 测试对话框 按钮 一个JDialog有名字自定义对话框 主要的将会打开 如果单击 是 选项自定义对话框主 其他JDialog named 自
  • 如何在 Spring 中使 @PropertyResource 优先于任何其他 application.properties ?

    我正在尝试在类路径之外添加外部配置属性资源 它应该覆盖任何现有的属性 但以下方法不起作用 SpringBootApplication PropertySource d app properties public class MyClass
  • 如何在java中将日期格式从YYMMDD更改为YYYY-MM-DD? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我从机器可读代码中获取日期格式为 YYMMDD 如何将其更改为 YYYY MM DD 例如我收到 871223 YYMMDD 我想把它改成
  • 如何在字段值无效的情况下更改 Struts2 验证错误消息?

    我在 Web 表单上使用 Struts2 验证 如果字段假设为整数或日期 则
  • 如何在.NET中使用java.util.zip.Deflater解压缩放气流?

    之后我有一个转储java util zip Deflater 可以确认它是有效的 因为 Java 的Inflater打开它很好 并且需要在 NET中打开它 byte content ReadSample sampleName var inp
  • Jetty、websocket、java.lang.RuntimeException:无法加载平台配置器

    我尝试在 Endpoint 中获取 http 会话 我遵循了这个建议https stackoverflow com a 17994303 https stackoverflow com a 17994303 这就是我这样做的原因 publi
  • JDBC 时间戳和日期 GMT 问题

    我有一个 JDBC 日期列 如果我使用 getDate 则会得到 date 仅部分2009 年 10 月 2 日但如果我使用 getTimestamp 我会得到完整的 date 2009 年 10 月 2 日 13 56 78 890 这正
  • Java Swing - 如何禁用 JPanel?

    我有一些JComponents on a JPanel我想在按下 开始 按钮时禁用所有这些组件 目前 我通过以下方式显式禁用所有组件 component1 setEnabled false 但是有什么办法可以一次性禁用所有组件吗 我尝试禁用
  • 使用 HtmlUnit 定位弹出窗口

    我正在构建一个登录网站并抓取一些数据的程序 登录表单是一个弹出窗口 所以我需要访问这个www betexplorer com网站 在页面的右上角有一个登录链接 写着 登录 我单击该链接 然后出现登录弹出表单 我能够找到顶部的登录链接 但找不
  • Hibernate 本机查询 - char(3) 列

    我在 Oracle 中有一个表 其中列 SC CUR CODE 是 CHAR 3 当我做 Query q2 em createNativeQuery select sc cur code sc amount from sector cost
  • java XMLSerializer 避免复杂的空元素

    我有这个代码 DocumentBuilderFactory factory DocumentBuilderFactory newInstance DocumentBuilder builder factory newDocumentBuil
  • java 中的蓝牙 (J2SE)

    我是蓝牙新手 这就是我想做的事情 我想获取连接到我的电脑上的蓝牙的设备信息并将该信息写入文件中 我应该使用哪个 api 以及如何实现 我遇到了 bluecove 但经过几次搜索 我发现 bluecove 不能在 64 位电脑上运行 我现在应
  • Java 正则表达式中的逻辑 AND

    是否可以在 Java Regex 中实现逻辑 AND 如果答案是肯定的 那么如何实现呢 正则表达式中的逻辑 AND 由一系列堆叠的先行断言组成 例如 foo bar glarch 将匹配包含所有三个 foo bar 和 glarch 的任何
  • 子类构造函数(JAVA)中的重写函数[重复]

    这个问题在这里已经有答案了 为什么在派生类构造函数中调用超类构造函数时 id 0 当创建子对象时 什么时候在堆中为该对象分配内存 在基类构造函数运行之后还是之前 class Parent int id 10 Parent meth void
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • 抛出 Java 异常时是否会生成堆栈跟踪?

    这是假设我们不调用 printstacktrace 方法 只是抛出和捕获 我们正在考虑这样做是为了解决一些性能瓶颈 不 堆栈跟踪是在构造异常对象时生成的 而不是在抛出异常对象时生成的 Throwable 构造函数调用 fillInStack

随机推荐

  • 【黑苹果教程】ELAN,FocalTech 以及 Synaptics 触控板驱动

    触控板上的手势操作应该是macOS的一大特色 但是黑苹果装完之后 很多人发现别说手势 很多基本的功能触控板都不能实现 此时你需要安装触控板驱动 本文参照osxlatitude论坛的ELAN FocalTech and Synaptics S
  • NMOS和PMOS详解以及电路设计

    一 简介 MOS管 是MOSFET的缩写 MOSFET金属 氧化物半导体场效应晶体管 简称金氧半场效晶体管 Metal Oxide Semiconductor Field Effect Transistor MOSFET 其中 G是栅极 S
  • apache 中 httpd.conf 的配置详解

    部分 1 全局环境 血泪提醒 rootDocument里面一定要有index php 或者index html 不然403错误 T T 本部分的表示将影响所有Apache的操作 例如 所能处理的并发请求数或配置文件地址 ServerType
  • Python拾遗2

    Python高级编程 第2版 1 常见的装饰器模式 参数检查 缓存 代理 上下文提供者 2 Python3新增函数注解 使用场景 类型检查 让IDE显示函数接受和返回的类型 函数重载 其他语言之间的桥梁 适配 谓词逻辑函数 数据库查询映射
  • python的输入与输出

    python输入 input 与输出 print 一 输入 input 在python3中 input会将接收到的用户输入自动存储为字符串类型 username input 输入用户名 cuihua print username cuihu
  • nlp-位置编码解析

    看到这里 是否记得前面提及Vaswani推出的Transformer结构 那么如果不使用RNN结构 是怎样表示位置信息的呢 在提信息位置技术前 先简介以下RNN和CNN RNN的序列结构不适合大规模并行训练 因为大家都知道 RNN对于序列问
  • matlab lstm工具箱,[转载]RNN以及LSTM的Matlab代码

    implementation of LSTM clc clear close all training dataset generation binary dim 8 largest number 2 binary dim 1 binary
  • LeetCode 667. 优美的排列 II

    题目链接 https leetcode cn problems beautiful arrangement ii C 代码如下 class Solution public vector
  • table元素无法固定列宽,width设置无效

    之前在做table的时候 因为不是用来做数据的展示的 所以对于具体的格式没有太高的要求 所以没有去深入了解 这次在做一个数据展示列表的时候使用table 因为假设每一个单元格数据是没有固定长度的 所以为了界面不会因为数据的变化格式发生大变化
  • okhttp报错:clientBuilder.sslSocketFactory(SSLSocketFactory) not supported on jdk 9+

    一 问题现象 最近在用okHttp处理http请求调用 编写jmeter压测脚本时 出现一个奇怪的问题 idea中可以正常调用 但是打成jar包后 在jmeter中去使用时 则调不通 报错 clientBuilder sslSocketFa
  • JavaScript在小程序网页部署实战

    服务端推理和前端推理对比 前端推理趋势 落地场景 单模型 多模型 全链路流程 JS2 0介绍 核心指标 技术方案 模型转换 核心组件 初始化和预测 计算方案 模型安全处理 加密目标 方案介绍 方案流程 关键路径 性能优化 代码处理 视频获取
  • webpack基础

    webpack基础 设置webpack模式的几种方法 npx webpack mode development mode的优先级高于env npx webpack env development webpack config js modu
  • HTML加载本地图片

    img src img src 也可以注意图片名就是1 而不是1 jpg 自己要加上对应的图片类型 转载于 https blog 51cto com 13930723 2372776
  • 计算机基本组成原理(简要笔记)

    计算机体系 一 冯 诺依曼体系结构 从Linux 服务器开发视角来看计算机 都是符合冯 诺依曼体系结构的 1 1 4大部分 1 1 1 输入 输出设备 输入设备 向计算机输入数据 比如通过摄像头 MIC 将图像 声音等转成二进制数据给计算机
  • flutter 顶部状态栏透明

    flutter 顶部状态栏透明 main js文件 void main 顶部状态栏透明 SystemChrome setSystemUIOverlayStyle SystemUiOverlayStyle statusBarColor Col
  • redis源码之:字典dict

    先来看看dict的大致结构 debug所用demo如下 void testDict int main int argc char argv testDict void testDict dict dict0 dictCreate hashD
  • SSH终端工具SecureCRT 8.5.4

    SecureCRT Mac版是mac上一款非常好用的SSH终端工具 可以为计算专业人士提供高级会话管理工具 从而提高效率工作并简化重复任务 SecureCRT为组织中的每个人提供安全的远程访问 文件传输和数据隧道 SecureCRT支持SS
  • OC门(Open Collector(Open Drain))

    OC门 又称集电极开路 漏极开路 与非门门电路 Open Collector Open Drain 为什么引入OC门 实际使用中 有时需要两个或两个以上与非门的输出端连接在同一条导线上 将这些与非门上的数据 状态电平 用同一条导线输送出去
  • 微信小程序——文字水平垂直居中

    记录一下CSS设置文字水平垂直居中 目录 1 代码说明 1 1 Html 1 2 CSS 2 效果 1 代码说明 对于直接在标签里面的文字 使用flex布局控制其中的文字水平和垂直居中 1 1 Html
  • java 使用sftp从远程服务器上传下载删除文件

    目录 前言 一 所需依赖 二 工具类 三 测试 1 判断指定目录是否存在 2 创建一个文件夹 3 删除指定文件 4 把文件上传到服务器上 5 从服务器上下载文件 6 执行Linux命令 前言 有时候我们需要让从代码里远程连接服务器进行文件上