用JSch实现远程传输文件并打包成jar

本文将简单介绍一下 JSch 这个Java的第三方库的一个简单用法,并以此为实例,讲解 IntelliJ 中打包成 jar 包的2种方式。

实现目标

我们的目标是,做出一个jar包,它能够实现类似于 scp 命令的远程传输文件的功能。用法如下:

java -jar UseJsch.jar scp /home/finix/1.txt 192.168.10.21:/home/finix/1.txt 

即,将本地的文件 /home/finix/1.txt 拷贝到远程机器 192.168.10.21 的 /home/finix/1.txt

简介 JSch

JSch 的官网是:http://www.jcraft.com/jsch/
JSch 是SSH2的纯Java实现。 它拥有诸多的和ssh相关的功能,比如 ssh 执行命令、scp等等,并被使用在一些著名的开源软件中。这个库的最新版本似乎就是 0.1.55, 于2018年左右就停止更新了。
本文不打算深入罗列JSch的各种功能,只是使用了其ChannelSftp类的put功能用于远程传输文件。现将ChannelSftp类的一些关键方法罗列如下:

  • put文件上传
  • get文件下载
  • cd进入指定目录
  • ls取得指定目录下的文件列表
  • rename重命名指定的文件或目录
  • mkdir创建目录
  • rmdir删除目录
  • rm删除指定文件

JSch的maven地址

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

Jsch的gradle写法(build.gradle)

dependencies {  'com.jcraft:jsch:0.1.55'  
}

核心代码

要实现scp文件的功能,可以使用下面的这个类。先看代码,其中具体使用已经写了注释,就不在这里介绍了。

package com.use_jsch;import com.jcraft.jsch.*;import java.io.*;
import java.util.Properties;public class UseJsch {public static void scpFile(int servicePort, String srcFilePath, String dstFilePath, String dstAddress) throws IOException {final String USER = "finix";final String PASSWORD = "123456789";final String PRIVATE_KEY_FILE = "/home/finix/.ssh/id_rsa";final String SESSION_TYPE = "sftp";final int SSH_TIMEOUT = 30000;  // 30 secondsfinal int SSH_COMMAND_ACK_TIMEOUT = 5000;   // 5 secondsfinal int CHANNEL_TIMEOUT = 5000;   // 5 secondsFile file = new File(srcFilePath);if (!file.exists()) {throw new RuntimeException(String.format("%s does not exist", srcFilePath));}Session session = null;Channel channel = null;ChannelSftp sftp = null;FileInputStream fileInputStream = null;try {JSch jsch = new JSch();// jsch.addIdentity(PRIVATE_KEY_FILE);Properties config = new Properties();config.put("StrictHostKeyChecking", "no");config.put("PreferredAuthentications", "publickey,password");session = jsch.getSession(USER, dstAddress, servicePort);session.setPassword(PASSWORD);session.setConfig(config);System.out.println("SCP_FILE: 1. session connecting...");session.connect(SSH_TIMEOUT);session.setTimeout(SSH_COMMAND_ACK_TIMEOUT);System.out.println("SCP_FILE: 2. open channel and connect...");channel = session.openChannel(SESSION_TYPE);channel.connect(CHANNEL_TIMEOUT);sftp = (ChannelSftp) channel;System.out.println("SCP_FILE: 3. scp file...");fileInputStream = new FileInputStream(file);sftp.setInputStream(fileInputStream);sftp.put(fileInputStream, dstFilePath);System.out.println("SCP_FILE: END");} catch (JSchException e) {System.err.println("SCP_FILE: JSchException: " + e);throw new RuntimeException("SCP_FILE: JSchException: " + e);} catch (IOException e) {System.err.println("SCP_FILE: IOException: " + e);throw new RuntimeException("SCP_FILE: IOException: " + e);} catch (Exception e) {System.err.println("SCP_FILE: ERROR: " + e);throw new RuntimeException("SCP_FILE: ERROR: " + e);} finally {if (fileInputStream != null) fileInputStream.close();if (channel != null) channel.disconnect();if (session != null) session.disconnect();}}public static void main(String[] args) {if (args.length != 3 || !args[0].equals("scp")) {System.out.println("Usage: java -jar UseJsch.jar scp <src_file_path> <ip>:<dest_file_path>");System.exit(1);}String srcFilePath = args[1];String[] destFileAndDestAddress = args[2].split(":");String dstFilePath = destFileAndDestAddress[1];String dstAddress = destFileAndDestAddress[0];try {System.out.printf("Start to scp file from %s to %s:%s%n", srcFilePath, dstAddress, dstFilePath);scpFile(22,srcFilePath, dstFilePath, dstAddress);}catch (Exception ex) {System.err.println("SCP FILE ERROR: " + ex);}}
}

这个java文件如果要直接测的话,可以将第一行 “package xxx” 删除,然后运行

java -cp lib/jsch-0.1.55.jar UseJsch.java /home/finix/1.txt 192.168.10.21:/home/finix/1.txt

运行效果就是:

Start to scp file from /home/finix/1.txt to 192.168.10.21:/home/finix/1.txt
SCP_FILE: 1. session connecting...
SCP_FILE: 2. open channel and connect...
SCP_FILE: 3. scp file...
SCP_FILE: END

值得一提的有2个地方:

  1. config.put("StrictHostKeyChecking", "no");
    这句话相当于 ssh 或 scp 的时候用的命令行参数 -o StrictHostKeyChecking=no, 其作用是,令其不再出现交互式的提问
The authenticity of host '192.168.10.21 (192.168.10.21)' can't be established.
ECDSA key fingerprint is SHA256:lSbwytjbqqvCC2FILkMb+M+yaeUTxEYPAPFTVIjTFOg.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

这是因为这个目标IP没有被加到~/.ssh/known_hosts文件中,所以询问你是否要继续连接。我们用了上面的选项-o StrictHostKeyChecking=no后,就不会再交互式提问,而是默认yes.

  1. config.put("PreferredAuthentications", "publickey,password");
    这一行代表优先使用的认证方式是publickeypassword这两种。
    (据说JSch提供了4种认证方式,但比较常用的应该还是以上提到的这2种)
    这一句的意思是优先使用publickey, 如果不行了再使用password. 如果要使用publickey, 那么其实还要再加一句
final String PRIVATE_KEY_FILE = "/home/finix/.ssh/id_rsa";
...
jsch.addIdentity(PRIVATE_KEY_FILE);

而在本文程序中, jsch.addIdentity(PRIVATE_KEY_FILE);被注释掉了,所以本文程序仍旧使用的是密码的方式。

程序部分就介绍到这里。下面是打包的流程。

打包为jar包

Step 1. 首先,在IntelliJ中新建一个gradle的项目,并加入源代码UseJsch.java, 而build.gradle中依赖包的加法已经在上文中描述过了,就不再重复。这里的目录结构大约是这样的:
在这里插入图片描述

Step 2. File -> Project Structure -> Module, 此处鼠标单击选中 “UseJsch” (不要选中其下面的“main”),此处应该能看到 “Gradle: com.jcraft:jsch:0.1.55”;若看不到,则此处需添加之。
这个添加的动作很重要:
1> 选中 “Module Source"
2> 点击加号 “+”
3> 弹出框中单击 Library
4> 继续的弹出框中选中 “Gradle: com.jcraft:jsch:0.1.55” , 点击 Add Selected
5> 最后点击OK.

在这里插入图片描述
Step 3. 还是在上面的界面,鼠标单击选中 “Artifacts”, 再点击“+” 和 “From modules with dependencies”
在这里插入图片描述

Step 4. 在弹出框中填“Module”、“Main class”、“JAR files from libraries”
在这里插入图片描述

注意,这里的 “JAR files from libraries” 有2个选项

  • extract to the target JAR
    这个选项的含义是:将第三方库的jar文件解压成class文件,然后拷贝到和主类相同的目录结构中。
    如果用了这个选项,我们就不用设置classpath来寻找第三方的库了。
  • copy to the output directory and link via manifest
    这个选项的含义是:第三方库将仍以jar包的形式存在,它会被拷贝到指定的地方(如lib目录);主类自己会被打一个jar包;因此需要在给主类打包的时候,指定MANIFEST文件中的classpath怎么写(见下文"打包方式-2")

打包方式-1: extract to the target JAR

Step 5.
上文Step-4中点击OK后,我们可以看到如下的界面:
在这里插入图片描述

注意,这里没有主类 UseJsch, 所以还得点击加号, 以添加主类。添加之后的效果如下:
在这里插入图片描述

注意,此处不用填写Class Path,因为第三方库已经被解压并和主类放置到了相同的目录结构下。
现在点击OK.

Step 6. Build -> Build Artifacts
在这里插入图片描述
此处点击 Build 或 Rebuild.

Build结束之后,我们在 output/artifacts/UseJsch_jar 目录下可以看到 UseJsch.jar 文件了!
在这里插入图片描述

右键选winrar打开,我们可以看到 jcraft 库的代码已经被解压和use_jsch包放到了一起:
在这里插入图片描述
最后,可以运行这个UseJsch.jar了:

$ java -jar UseJsch.jar scp /home/finix/1.txt 192.168.10.21:/home/finix/1.txt
Start to scp file from /home/finix/1.txt to 192.168.10.21:/home/finix/1.txt
SCP_FILE: 1. session connecting...
SCP_FILE: 2. open channel and connect...
SCP_FILE: 3. scp file...
SCP_FILE: END

打包方式-2: copy to the output directory and link via manifest

在上文Step-4的时候选中 “copy to the output directory and link via manifest”, 点OK
然后可以看到如下的界面。
在这里插入图片描述

注意,
这里我们已经可以看到第三方库 jsch-0.1.55.jar了,这是我们在Step-2所作的工作的效果;
(如果没有Step-2的工作,这里将不会显示第三方库,因此就需要手动添加:点击加号“+”,再点击 Library Files)。
但是,此时并没有 主类,所以我们需要手动加主类添加上去:**单击选中”UseJsch.jar“, 点击加号,再点击“Module Output”*, 如下:
在这里插入图片描述

选中主类,最后点击OK, 效果见下一步的图。

Step-5. 点击选中“UseJsch.jar”, 然后在下面出现的框中填写 “Manifest File”、“Main Class”、和“Class Path”
在这里插入图片描述

最后,剩下来的步骤和打包方式-1相同,就是Build -> Build Artifacts.
出来的效果是这样的。
在这里插入图片描述
运行效果也是一样,不再赘述。

(完)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

arm的状态寄存器

目录 一、arm 的 PSRs二、CPSR2.1 CPSR_cxsf 三、SPSR四、APSR 一、arm 的 PSRs arm 中有很多程序状态寄存器&#xff08;Program Status Registers&#xff0c;PSRs&#xff09;用于存储处理器的状态信息&#xff0c;包括 CPSR\SPSR\FPSR\APSR 等&#xff1a; CPSR&#xff…

OpenHarmony实战:Makefile方式组织编译的库移植

以yxml库为例&#xff0c;其移植过程如下文所示。 源码获取 从仓库获取yxml源码&#xff0c;其目录结构如下表&#xff1a; 表1 源码目录结构 名称描述yxml/bench/benchmark相关代码yxml/test/测试输入输出文件&#xff0c;及测试脚本yxml/Makefile编译组织文件yxml/.gitat…

计算机网络-从输入网址到访问网站的全过程

当我们在浏览器中输入一个网址并按下回车键时&#xff0c;会发生一系列复杂的过程&#xff0c;最终使我们能够看到网页的内容。以下是这个过程的详细步骤&#xff1a; 客户端&#xff1a;首先&#xff0c;用户在浏览器中键入网址&#xff0c;然后浏览器会根据这个网址生成一个H…

MySQL count函数的使用

count&#xff08;&#xff09;函数在使用时参数好像不能设置为表达式&#xff0c;只能设置成指定字段或* 比如在查询性别为男的成员数目时不能写&#xff1a; select count(gendermale) from user_profile ; 否则直接得到6&#xff0c;也就是等价于select count(gender) fro…

java子集(力扣Leetcode78)

子集 力扣原题链接 问题描述 给定一个整数数组 nums&#xff0c;数组中的元素互不相同。返回该数组所有可能的子集&#xff08;幂集&#xff09;。解集不能包含重复的子集。可以按任意顺序返回解集。 示例 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#x…

LabVIEW专栏三、探针和断点

探针和断点是LabVIEW调试的常用手段&#xff0c;该节以上一节的"测试耗时"为例 探针可以打在有线条的任何地方&#xff0c;打上后&#xff0c;经过这条线的所有最后一次的数值都会显示在探针窗口。断点可以打在程序框图的所有G代码对象&#xff0c;包括结构&#xf…

NVIDIA Jetson Xavier NX入门-镜像为jetpack5(3)——pytorch和torchvision安装

NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#xff08;3&#xff09;——pytorch和torchvision安装 镜像为jetpack5系列&#xff1a; NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#xff08;1&#xff09;——镜像烧写 NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#…

第14章 数据结构与集合源码

一 数据结构剖析 我们举一个形象的例子来理解数据结构的作用&#xff1a; 战场&#xff1a;程序运行所需的软件、硬件环境 战术和策略&#xff1a;数据结构 敌人&#xff1a;项目或模块的功能需求 指挥官&#xff1a;编写程序的程序员 士兵和装备&#xff1a;一行一行的代码 …

代码随想录-力扣刷题-总结笔记02

代码随想录&#xff1a;代码随想录力扣&#xff1a;力扣 (LeetCode) 全球极客挚爱的技术成长平台 代码随想录-力扣刷题-总结笔记01代码随想录-力扣刷题-总结笔记02 目录 01、代码随想录 00、其他 ArrayList转数组 07、二叉树 7.0、递归法 7.1、二叉树的层序遍历模板 7.2…

vite.config.js

Vue3vite vite和webpack区别&#xff1f; 1.vite服务器启动速度比webpack快&#xff0c;由于vite启动的时候不需要打包&#xff0c;也就无需分析模块依赖、编译&#xff0c;所以启动速度非常快。当浏览器请求需要的模块时&#xff0c;再对模块进行编译&#xff0c;这种按需动态…

RPA自动化微信自动清理僵尸粉工具

1、视频演示 RPA自动化清理微信僵尸粉 2、核心功能点 通过给好友测试转账&#xff0c;如果能转账则表示是正常的好友关系&#xff0c;否则&#xff0c;则表示对方将你拉黑或者删除了。 3、流程图 4、代码长图分享 5、使用手册 1、准备好一部安卓手机和一根可以调试手机的USB…

搞学术研究好用免费的学术版ChatGPT网站-学术AI

学术版ChatGPThttps://chat.uaskgpt.com/mobile/?user_sn88&channelcsdn&scenelogin 推荐一个非常适合中国本科硕士博士等学生老师使用的学术版ChatGPT&#xff0c; 对接了超大型学术模型&#xff0c;利用AI技术实现学术润色、中英文翻译&#xff0c;学术纠错&#…

【Leetcode笔记】102.二叉树的层序遍历

目录 知识点Leetcode代码&#xff1a;ACM模式代码&#xff1a; 知识点 vector、queue容器的操作 对vector<int> vec;做插入元素操作&#xff1a;vec.push_back(x)。对queue<TreeNode*> que;做插入元素操作&#xff1a;que.push(root);。队列有四个常用的操作&…

【剑指offr--C/C++】JZ9 用两个栈实现队列

一、题目 二、思路与代码 栈是先进后出&#xff0c;队列是先进先出&#xff0c;也就是说从push角度来说二者顺序相同&#xff0c;而从pop的角度来说二者顺序正好是相反的&#xff0c;那我们就可以一个栈中push,一个栈中pop。在一个stack1中进行push&#xff0c;然后每当需要pop…

LInux脚本学习

1.注释 #单行注释 以 # 字符开头就是单行注释 当然第一行除外&#xff0c;比较特殊 2.多行注释 3.Shell文件的作用 Shell文件就是linux命令集 4.sh脚本的执行方式 bash xxx.sh 5.新建的文件会没有执行权限 #为文件赋予执行权限 chmod ux xxx.sh 6.编写规范 #!/bin/bash #…

二维码:技术、商业与未来

title: 二维码&#xff1a;技术、商业与未来 date: 2024/4/3 19:12:28 updated: 2024/4/3 19:12:28 tags: 二维码技术商业应用移动支付物联网AR/VR融合智能家居数字化社会 第一章&#xff1a;引言 1. 二维码在数字化时代的重要性和普及程度 在数字化时代&#xff0c;二维码作…

红黑树介绍与模拟实现(insert+颜色调整精美图示超详解哦)

红黑树 引言红黑树的介绍实现结点类insert搜索插入位置插入调整当parent为gparent的左子结点当parent为gparent的右子结点 参考源码测试红黑树是否合格总结 引言 在上一篇文章中我们认识了高度平衡的平衡二叉树AVL树&#xff1a;戳我看AVL树详解哦 &#xff08;关于旋转调整的…

vscode安装通义灵码

作为vscode的插件&#xff0c;直接使用 通义灵码-灵动指间&#xff0c;快码加编&#xff0c;你的智能编码助手 通义灵码&#xff0c;是一款基于通义大模型的智能编码辅助工具&#xff0c;提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研…

蓝桥杯单片机速成8-NE555频率测量

一、原理图 NOTE&#xff1a;使用NE555测量频率之前&#xff0c;需要将J3-15(SIGNAL)与J3-16(P34短接) 在使用矩阵键盘的时候也记得把跳冒拔下&#xff0c;因为有公共引脚P34 又是因为他的输出引脚是P34&#xff0c;所以只能用定时器0来作为计数器进行频率测量了 二、代码实现 …

基于java的电影院售票网站

开发语言&#xff1a;Java 框架&#xff1a;ssm 技术&#xff1a;JSP JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclip…