Springboot整合Jsch-Sftp

背景

  开发一个基于jsch的sftp工具类,方便在以后的项目中使用。写代码的过程记录下来,作为备忘录。。。

Maven依赖

  • springboot依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.0</version>
</parent>
  • jsch依赖
 <dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.55</version>
</dependency>
  • 完整依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>jsch-sftp</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.0</version></parent><dependencies><!-- web应用相关 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 单元测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><!-- jsch SFTP --><dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.55</version></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies></project>

项目结构

在这里插入图片描述

Sftp连接工具类

  • JschSftpRun: 项目启动类
package cn.com.soulfox;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;/*** 启动类** @author xxxx* @create 2024/7/5 11:50*/
@SpringBootApplication
public class JschSftpRun {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(JschSftpRun.class, args);}
}
  • JschSftpConneciton: 创建sftp连接工具类
      用于创建sftp连接,类中提供了创建sftp连接的方法,另外还提供了在创建sftp连接失败后,重新尝试创建连接的方法
package cn.com.soulfox.jsch;import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;/*** @author xxxx* @create 2024/7/4 12:15*/
@Slf4j
public class JschSftpConneciton {private static final String SFTP_PROTOCOL = "sftp";private static final Integer DEFAULT_RETRY_COUNT_5 = 5;private static final Long SLEEP_ITME_1000 = 1000L;//每次重试的时间间隔private String host;private Integer port;private String username;private String password;private Integer sessionTimeout;private Integer connectionTimeout;public JschSftpConneciton setHost(String host) {this.host = host;return this;}public JschSftpConneciton setPort(Integer port) {this.port = port;return this;}public JschSftpConneciton setUsername(String username) {this.username = username;return this;}public JschSftpConneciton setPassword(String password) {this.password = password;return this;}public JschSftpConneciton setSessionTimeout(Integer sessionTimeout) {this.sessionTimeout = sessionTimeout;return this;}public JschSftpConneciton setConnectionTimeout(Integer connectionTimeout) {this.connectionTimeout = connectionTimeout;return this;}/*** 返回SftpWrapper对象,是为了方便释放Session,Channel,ChannelSftp资源* SFTP连接服务器*/public SftpWrapper connect() throws  Exception {JSch jsch = new JSch();Session session = null;Channel channel = null;ChannelSftp sftp = null;try {session = jsch.getSession(username, host, port);if (session == null) {throw new JSchException("create session error");}//设置登陆主机的密码session.setPassword(password);//设置第一次登陆的时候提示,可选值:(ask | yes | no)session.setConfig("StrictHostKeyChecking", "no");//设置登陆超时时间session.connect(sessionTimeout);session.sendKeepAliveMsg();//创建sftp通信通道channel = session.openChannel(SFTP_PROTOCOL);channel.connect(connectionTimeout);sftp = (ChannelSftp) channel;return new SftpWrapper(session, channel, sftp);}catch (JSchException e){log.error("SFTP连接异常:", e);if (sftp != null ) {sftp.disconnect();}if (channel != null ) {channel.disconnect();}if (session != null ) {session.disconnect();}throw e;} catch (Exception e1) {log.error("SFTP连接异常:", e1);if (sftp != null ) {sftp.disconnect();}if (channel != null ) {channel.disconnect();}if (session != null ) {session.disconnect();}throw e1;}}/*** 获取sftp连接,获取连接失败时会重试,* 默认重试次数:5次* @return* @throws Exception*/public SftpWrapper connectWithRetry() throws Exception {return connectWithRetry(DEFAULT_RETRY_COUNT_5);}public SftpWrapper connectWithRetry(int retryCount) throws Exception {//最大重试次数int maxRetryCount = DEFAULT_RETRY_COUNT_5;if(retryCount > 0){maxRetryCount = retryCount;}int retry = 0;Throwable t = null;do {try {SftpWrapper channelSftpWrapper = this.connect();if(channelSftpWrapper != null){t = null;return channelSftpWrapper;}} catch (Exception e) {t = e;}try {Thread.sleep(SLEEP_ITME_1000);//休息1秒} catch (InterruptedException e) {}}while (retry++ < maxRetryCount);if(t != null){throw new Exception(t);}return null;}}
  • SftpWrapper: sftp连接对象包装类,属性包括Session,Channel,ChannelSftp
      执行sftp操作有ChannelSftp就可以了,使用Sftp包装类,是为了方便关闭资源
package cn.com.soulfox.jsch;import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.Session;
import lombok.AllArgsConstructor;
import lombok.Data;/*** SftpWrapper类简单包装ChannelSftl对象,方便关闭资源* @author xxxx* @create 2024/7/4 14:26*/
@AllArgsConstructor//生成全字段,构造方法
@Data //生成 getter,setter方法
public class SftpWrapper {private Session session = null;private Channel channel = null;private ChannelSftp sftp = null;/*** 关闭资源*/public void disconnect() {if (sftp != null && sftp.isConnected()) {sftp.disconnect();}if (channel != null && channel.isConnected()) {channel.disconnect();}if (session != null && session.isConnected()) {session.disconnect();}}
}
  • JschSftpConfig: jsch sftp配置类
      初始化 jsch sftp
package cn.com.soulfox.config;import cn.com.soulfox.jsch.JschSftpConneciton;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;/*** @author xxxx* @create 2024/7/4 12:12*/
@Configuration
public class JschSftpConfig {@Value("${jsch.sftp.host}")private String host;@Value("${jsch.sftp.port:22}")private Integer port;@Value("${jsch.sftp.username}")private String username;@Value("${jsch.sftp.password}")private String password;@Value("${jsch.sftp.session-timeout:60000}")private Integer sessionTimeout;//单位毫秒@Value("${jsch.sftp.connect-timeout:5000}")private Integer connectTimeout;//单位毫秒@Bean@Lazypublic JschSftpConneciton jschSftpConneciton(){return new JschSftpConneciton().setHost(host).setPort(port).setUsername(username).setPassword(password).setSessionTimeout(sessionTimeout).setConnectionTimeout(connectTimeout);}}

sftp连接信息配置在文件application.yml里
jsch:
sftp:
host: 172.168.xxx.xx
port: 1221 #默认22,1221公司自己定义的,这里要配置正确
username: xxxx #远程服务器用户名
password: xxxx #远程服务器密码
sftp连接信息

SftpUitl 工具类,提供下载,上传文件功能

package cn.com.soulfox.jsch;import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.io.*;/*** @author xxxx* @create 2024/7/4 14:28*/
@Component
@Slf4j
public class JschSftpUtil {private static JschSftpConneciton jschSftpConneciton;@Autowiredpublic void setJschSftpConneciton(JschSftpConneciton jschSftpConneciton) {JschSftpUtil.jschSftpConneciton = jschSftpConneciton;}/*** 下载文件* @param remotePath            远程目录* @param downloadFileName      待下载的远程文件名称* @param localSavePath         下载文件保存的本地目录*/public static void downloadFile(String remotePath, String downloadFileName, String localSavePath) {SftpWrapper sftpWrapper = null;try {//sftp连接对象sftpWrapper = jschSftpConneciton.connectWithRetry();//进入远程服务器指定的目录sftpWrapper.getSftp().cd(remotePath);if (!checkLocalPath(localSavePath)) {log.info("本地目录[{}]不存在,且新建失败+++++", localSavePath);return;}String localFile = checkPathEnd(localSavePath) + downloadFileName;File outFile = new File(localFile);sftpWrapper.getSftp().get(downloadFileName, new FileOutputStream(outFile));log.info("从远程目录[{}]下载文件[{}]到本地目录[{}]成功", remotePath, downloadFileName, localSavePath);} catch (SftpException e) {log.info("从远程目录[{}]下载文件[{}]到本地目录[{}]失败", remotePath, downloadFileName, localSavePath);log.error("下载文件失败: ", e);} catch (Exception e) {log.info("从远程目录[{}]下载文件[{}]到本地目录[{}]失败", remotePath, downloadFileName, localSavePath);log.error("下载文件失败: ", e);} finally {if (sftpWrapper != null) {sftpWrapper.disconnect();}}}/**** @param localDir              保存上传文件的本地目录* @param uploadFileName        上传文件名称* @param remoteSaveDir         保存上传文件的远程目录, 建议使用绝对路径*                              如果使用相对路径,建议基准目录使用sfpt登录后所在的目录*                              这个目录,使用channelSftp.goHome()可以获取*/public static void uploadFile(String localDir, String uploadFileName, String remoteSaveDir) {String uploadFilePath = checkPathEnd(localDir) + uploadFileName;File uploadFile = new File(uploadFilePath);uploadFile(uploadFile, remoteSaveDir);}/*** 上传文件* @param uploadFilePath        本地文件的路径* @param remoteSaveDir         保存上传文件的远程目录, 建议使用绝对路径*                              如果使用相对路径,建议基准目录使用sfpt登录后所在的目录*                              这个目录,使用channelSftp.goHome()可以获取*/public static void uploadFile(String uploadFilePath, String remoteSaveDir) {File uploadFile = new File(uploadFilePath);uploadFile(uploadFile, remoteSaveDir);}/*** 上传文件* @param uploadFile        上传文件的File对象* @param remoteSavePath    保存上传文件的远程目录, 建议使用绝对路径*                          如果使用相对路径,建议基准目录使用sfpt登录后所在的目录*                          这个目录,使用channelSftp.goHome()可以获取*/public static void uploadFile(File uploadFile, String remoteSavePath) {if(uploadFile == null ){log.info("本地文件对象不存在++++");return;}if(!uploadFile.exists()){log.info("本地文件[{}]不存在", uploadFile.getAbsoluteFile());return;}InputStream is = null;try {is = new FileInputStream(uploadFile);} catch (FileNotFoundException e) {log.info("获取本地文件[{}]的文件流失败", uploadFile.getAbsoluteFile());log.error("获取文件流失败: ", e);if(is != null){try {is.close();} catch (IOException ioException) {}}return;}SftpWrapper sftpWrapper = null;try {//sftp连接对象sftpWrapper = jschSftpConneciton.connectWithRetry();//检查远程目录,不存在则创建createLinuxRemoteDirs(sftpWrapper.getSftp(), remoteSavePath);//进入用户home目录,sftpWrapper.getSftp().cd(sftpWrapper.getSftp().getHome());//保证当前目录在上传文件保存的目录sftpWrapper.getSftp().cd(remoteSavePath);//上传文件sftpWrapper.getSftp().put(is, uploadFile.getName());} catch (SftpException e) {log.info("上传本地文件[{}]到远程目录[{}]失败", uploadFile.getAbsoluteFile(), remoteSavePath);log.error("上传本地文件失败: ", e);} catch (Exception e) {log.info("上传本地文件[{}]到远程目录[{}]失败", uploadFile.getAbsoluteFile(), remoteSavePath);log.error("上传本地文件失败: ", e);} finally {if (sftpWrapper != null) {sftpWrapper.disconnect();}if(is != null){try {is.close();} catch (IOException e) {}}}}/*** 检查目录结是否以目录分隔符结尾* 如果不是,则加上目录分隔符结尾** @param localPath 本地目录* @return*/private static String checkPathEnd(String localPath) {if (localPath.endsWith("/") || localPath.endsWith("\\")) {return localPath;}return localPath + File.separator;}/*** 检查本地目录是否存在,不存在就创建。* 为了防止其他线程已创建目录,加上了重试代码** @param localPath 本地目录* @return*/private static boolean checkLocalPath(String localPath) {int maxRetryCount = 5;int retry = 0;do {File localDir = new File(localPath);if (localDir.exists()) {return true;}boolean result = localDir.mkdirs();if (result) {return true;}try {Thread.sleep(1000L);//休息1秒} catch (InterruptedException e) {}} while (retry++ < maxRetryCount);return false;}/*** 检查和创建[ linux系统 ]的远程多级目录,* 外部调用, 单纯的创建远程目录,不作其他操作* @param remoteDir     远程目录* @throws SftpException*/public static void createLinuxRemoteDirs( String remoteDir) throws SftpException {SftpWrapper sftpWrapper = null;try {sftpWrapper = jschSftpConneciton.connectWithRetry();createLinuxRemoteDirs(sftpWrapper.getSftp(), remoteDir);} catch (SftpException e) {log.info("创建Linux远程目录[{}]失败", remoteDir);log.error("创建Linux远程目录失败: ", e);} catch (Exception e) {log.info("创建Linux远程目录[{}]失败", remoteDir);log.error("创建Linux远程目录失败: ", e);} finally {if (sftpWrapper != null) {sftpWrapper.disconnect();}}}/*** 检查和创建[ linux系统 ]的远程多级目录,* linux系统目录分隔符是 “/”* 内部上传文件的方法调用** @param sftpChannel* @param remoteDir  远程目录* @throws SftpException*/public static void createLinuxRemoteDirs(ChannelSftp sftpChannel, String remoteDir) throws SftpException {if(remoteDir == null || "".equals(remoteDir)){log.info("待创建的远程目录为空++++++++");return;}String[] dirs = remoteDir.split("/");;if(dirs == null || dirs.length == 0){log.info("拆分目录[{}]失败,没有获取到目录数组", remoteDir);return;}//进入用户home目录,保证初始目录正确sftpChannel.cd(sftpChannel.getHome());if( dirs.length == 1){//只有一层目录,直接处理try {sftpChannel.cd(dirs[0]);} catch (SftpException e) {if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {log.info("开始创建远程目录[{}]", dirs[0]);sftpChannel.mkdir(dirs[0]);} else {throw e;}}return;}StringBuilder sb = new StringBuilder();//处理第一个元素if(remoteDir.startsWith(".")){//相对路径,把缺少的路径补上sb.append(sftpChannel.getHome()).append("/");}else if(remoteDir.startsWith("/")){//绝对路径,把"/"放到目录开头sb.append("/");}else {//既不是”/“开头,也不是”.“开头//属于相对路径的一种情况try {//先处理第一层目录sftpChannel.cd(dirs[0]);} catch (SftpException e) {if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {log.info("开始创建远程目录[{}]", dirs[0]);sftpChannel.mkdir(dirs[0]);} else {throw e;}}//把已处理的目录加上sb.append(sftpChannel.getHome()).append("/").append(dirs[0]).append("/");}//从第二个元素开始创建不存在的目录for (int i = 1; i < dirs.length; i++) {String dir = dirs[i];if (dir.isEmpty() ) {//跳过空字符串continue;}sb.append(dir + "/");try {sftpChannel.cd(sb.toString());} catch (SftpException e) {if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {log.info("开始创建远程目录[{}]", sb.toString());sftpChannel.mkdir(sb.toString());} else {throw e;}}}
//        for (String dir : dirs) {
//            if (dir.isEmpty() || dir.contains(".")) {
//                //跳过空字符串,和"."字符串
//                continue;
//            }
//            sb.append(dir + "/");
//            try {
//                sftpChannel.cd(sb.toString());
//            } catch (SftpException e) {
//                if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
//                    sftpChannel.mkdir(sb.toString());
//                } else {
//                    throw e;
//                }
//            }
//        }}
}

单元测试

  • JschSftpConfigTest: 测试类
package cn.com.soulfox.config;import cn.com.soulfox.JschSftpRun;
import cn.com.soulfox.jsch.JschSftpConneciton;
import cn.com.soulfox.jsch.JschSftpUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;/*** @author xxxx* @create 2024/7/5 12:57*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = JschSftpRun.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class JschSftpConfigTest {@Autowiredprivate JschSftpConneciton sftpConneciton;/*** 下载文件*/@Testpublic void testDownload(){//从远程服务器上的下载 /home/jiyh/ 目录下的 testabc.txt//下载文件保存到 d:\jiyhString remotePath = "/home/jiyh/";String downloadFileName = "testabc.txt";String localSavePath = "d:\\jiyh";JschSftpUtil.downloadFile(remotePath, downloadFileName, localSavePath);}/*** 上传文件*/@Testpublic void testUpload(){//上传传本地 d:\jiyh 目录下的 test123.txt文件//到远程 /home/jiyh/test/test 目录//目录不存在,会自动创建JschSftpUtil.uploadFile("d:\\jiyh", "test123.txt", "/home/jiyh/test/test");}
}
  • 在远程服务器准备测试文件 文件内容随便,这里我准备的内容为“112dadfdefee”
    在这里插入图片描述

  • 测试下载功能
    测试结果:
    在这里插入图片描述

  • 测试上传功能 :在本地 d:/jiyh 目录准备测试文件“test123.txt”,内容为“dfdfdfdfdaerwrt”
    测试结果
    在这里插入图片描述

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

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

相关文章

codeforces 1633A

文章目录 1. 题目链接2. 题目代码正确代码错误代码 3. 题目总结 1. 题目链接 Div. 7 2. 题目代码 正确代码 #include<iostream> using namespace std; int main(){int testCase;cin >> testCase;while(testCase --){int ingeter;cin >> ingeter;if(!(inget…

SpringBoot彩蛋之定制启动画面

写在前面 在日常开发中&#xff0c;我们经常会看到各种各样的启动画面。例如以下几种 ① spring项目启动画面 ② mybatisplus启动画面 ③若依项目启动画面 还有很多各式各样好看的启动画面&#xff0c;那么怎么定制这些启动画面呢&#xff1f; 一、小试牛刀 ① 新建一个Spr…

Java 8 到 Java 22 新特性详解

Java 8 到 Java 22 新特性详解 Java自发布以来一直在不断演进&#xff0c;添加新特性以提升开发效率和性能。本文将介绍Java 8到Java 22的主要新特性&#xff0c;帮助开发者了解各版本的新功能和改进。 Java 8 (2014) 1. Lambda 表达式 Lambda 表达式允许使用简洁的语法定义…

SQL 之 concat_ws和concat的区别

concat_ws和concat都是用于连接字符串的函数&#xff0c;但它们在使用上有一些区别&#xff1a; 一、concat、concat_ws函数格式&#xff1a; concat格式&#xff1a; concat&#xff08;参数1,参数2,…参数n&#xff09;&#xff0c;如果要加’分隔符’直接写在 各参数中间就…

关于微信支付-商户平台:查询订单提示“查询失败:操作失败,请稍候重试”的分析

目录 引子 分析 应对 小结 引子 在开发和实施微信 JSAPI 支付的应用后&#xff0c;我们遇到了一些问题&#xff0c;订单的状态更新不正常&#xff0c;当然我们首先需要从自身寻找原因和完善解决问题的办法和方案。在支付的过程中&#xff0c;客户会给我们一些反馈&#xf…

Open-Sora1.2环境搭建推理测试

引子 前阵子写了一篇Open-Sora1.0环境搭建&推理测试&#xff08;Open-Sora1.0环境搭建&推理测试_自己搭建sora服务-CSDN博客&#xff0c;感兴趣的童鞋&#xff0c;请移步&#xff09;。Open-Sora1.1发布的时候&#xff0c;撇了一眼新闻。后面一转头&#xff0c;忘记这…

ARL联动AWVS实现自动化漏洞扫描

0x01 前言 很多场景下需要大范围的扫描漏洞和快速排查互联网暴露面的漏洞&#xff0c;需要使用这种自动化的手段&#xff0c;常规渗透测试的找互联网暴露面是&#xff0c;域名>子域名>IP>C段>端口&#xff0c;可以手动收集&#xff0c;也可以借助一些网络搜索引擎…

css中伪元素 :: before的用法

在CSS中&#xff0c;伪元素 ::before 用于在选定元素的内容前插入内容。它常用于添加图标、文本或装饰性的元素&#xff0c;而不需要在HTML中实际添加额外的标签。 以下是一个示例说明 ::before 的用法&#xff1a; <!DOCTYPE html> <html lang"en"> &…

一文解决Postman请求发送难题

标题&#xff1a;【技术深度解析】一文解决Postman请求发送难题 在API开发和测试过程中&#xff0c;Postman作为一款强大的工具&#xff0c;其重要性不言而喻。然而&#xff0c;开发者们时常会遇到Postman无法发送请求的问题&#xff0c;这无疑会严重影响开发进度和测试效率。…

wordpress网站添加一个临时维护功能

把以下代码放到functions.php文件中&#xff0c;主要用网站临时维护或者用于备案。事情做好了&#xff0c;把以下代码删除即可&#xff01;&#xff01;&#xff01; 有时遇到一些情况&#xff0c;比如站点需要闭站备案、或者被要求停站等等&#xff0c;我们就可以使用本文的功…

开发个人Go-ChatGPT--5 模型管理 (三)

开发个人Go-ChatGPT–5 模型管理 (三) 服务部署 go-ChatGPT项目涉及的中间件服务较多&#xff0c;以下部署文件目录&#xff1a; |-- chat-api | |-- etc | | -- config.yaml | -- logs |-- chat-rpc | |-- etc | | -- config.yaml | -- logs |-- docker-co…

CP AUTOSAR标准之UDPNetworkManagement(AUTOSAR_CP_SWS_UDPNetworkManagement)(更新中……)

1 简介和功能概述 本文档介绍了AUTOSAR UDP网络管理(UdpNm)的概念、核心功能、可选功能、接口和配置问题。UdpNm旨在成为一项可选功能。它旨在与TCP/IP堆栈协同工作,独立于所用通信系统的物理层。AUTOSAR UDP网络管理是一种独立于硬件的协议,可用于基于TCP/IP的系统(有关限制…

卡尔曼滤波Q和R怎么调

卡尔曼滤波器是一种有效的估计算法&#xff0c;主要用于在存在噪声的环境中估计动态系统的状态。它通过结合预测模型&#xff08;系统动态&#xff09;和观测数据&#xff08;包括噪声&#xff09;来实现这一点。在卡尔曼滤波中&#xff0c;调整过程噪声协方差矩阵 ( Q ) 和测量…

Java中的标准输入流简述

System.in简介 System.in 是标准输入流&#xff0c;通常与键盘输入相关联。它是 InputStream 类型的对象&#xff0c;Java 使用它来从控制台接收用户输入。在 Java 程序中&#xff0c;通常使用 Scanner 类来读取 System.in 的输入。 以下是一些关键点&#xff0c;解释为什么需…

Kubernetes运维工程师必备:K8s 基础面试题精编(一)

Kubernetes运维工程师必备:K8s 基础面试题精编(一) 1. 什么是Kubernetes?2. Kubernetes如何实现容器编排?3. 说出k8s的常见资源对象?4. 什么是pod?5. Deployment介绍及使用?6. statefulesets介绍及使用?7. statefulesets和deployment区别?8. 什么是调度器(Scheduler…

The First项目报告:NvirWorld与区块链游戏的未来

根据官方公告&#xff0c;The Fisrt现货区将于2024年7月2日16:00上架NVIR/USDT交易对&#xff0c;NVIR是NvirWorld平台的原生代币。作为一个去中心化解决方案&#xff0c;NvirWorld为开发者提供了一个简化且适应性强的环境&#xff0c;旨在通过优化的扩展解决方案来降低交易成本…

docker 本地部署大模型(ollama)

docker 安装 ollama docker search ollama docker pull ollama/ollama###docker下载ollama部署 docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama### 下载模型 docker exec -it ollama ollama pull llama3### 交互式运行模型docker exec -i…

ECharts 最小高度设置指南

下面提供一份关于ECharts中设置最小高度的专业而详细的文档。这份文档将涵盖不同图表类型的最小高度设置方法&#xff0c;适合初学者学习和参考。 ECharts 最小高度设置指南 1. 通用属性 对于大多数图表类型&#xff0c;可以使用以下通用属性来控制最小高度&#xff1a; 1.…

算法 —— 二分查找

目录 二分查找 在排序数组中查找元素的第一个和最后一个位置 搜索插入位置 x的平方根 山峰数组的峰顶索引 寻找峰值 搜索旋转排序数组中的最⼩值 点名 二分查找模板分为三种&#xff1a;1、朴素的二分模板 2、查找左边界的二分模板 3、查找右边界的二分模板&#xf…

【基于R语言群体遗传学】-12-超显性与次显性

欢迎先看前面的博客&#xff0c;再继续进行后面的内容&#xff1a; 群体遗传学_tRNA做科研的博客-CSDN博客 当杂合子的适应度超出纯合子的范围时&#xff0c;二倍体能够展现出更多令人着迷的选择实例。这种形式的一种是杂合子优势&#xff0c;或称为“超显性”&#xff0c;其…