JRT多平台初始化程序

这么多年客户端一直只做Windows,所以初始化程序用C#写个Exe,按网站生成的下载清单文件一个个下载和部署客户端环境是可以的。新的由于设计目标就是支持多平台的,所以需要重新考虑初始化设计。

介绍和演示视频

设计目标有以下:
1.方便更新客户端程序的单个文件
2.多平台初始化体验接近
3.不能运行脚本的电脑也要让手工能下载压缩包自己放程序
4.尽可能少占用服务器空间
5.服务器上程序修改之后要能自动更新下载的zip包

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

文件布局
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

压缩包生成目录,在加载环境下载页面时候会检查是否需要生成压缩包文件,下列情况会触发生成新压缩包:
1.download/clienttmp目录没windows.zip或linux.zip
2.download/data目录没linuxinitjrt.sh或windowsinitjrt.ps1
3.download/client下文件比download/clienttmp目录没windows.zip或linux.zip新
在这里插入图片描述
环境下载页检查之后生成的压缩包
在这里插入图片描述

在线初始化脚本的模板
linux

#!/bin/bash
#shell在linux上初始化jrt
#20240413
#zlz
#initfile由程序构造初始化脚本时候替换成下载文件命令
#----------------------------------------------------------
rm -y /usr/share/JRTBase/linux.zip
${initfile}
cd /usr/share/JRTBase
unzip linux.zip
#调用本地初始化脚本
touch /usr/share/JRTBase/linux/inlinecall.flag
#调用本地初始化脚本
bash /usr/share/JRTBase/linux/install.sh

windows

#get-executionpolicy
#set-executionpolicy remotesigned
Add-Type -TypeDefinition @"  using System.Net;  using System.Security.Cryptography.X509Certificates;  public class TrustAllCertsPolicy : ICertificatePolicy {  public bool CheckValidationResult(  ServicePoint srvPoint, X509Certificate certificate,  WebRequest request, int certificateProblem) {  return true;  }  }  
"@  [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12  
Write-Host "Welcome to the JRT-Windows initialization script, which will perform initialization operations"
Write-Host "downloading windows.zip please wait"
${initfile}
Write-Host "unzip windows.zip"
Expand-Archive -Path 'C:\JRTBase\windows.zip' -DestinationPath 'C:\JRTBase'
Write-Host "copy link to desktop"
$sourcePath = "C:\JRTBase\windows\JRTClient-win\JRTClient.lnk" 
$desktopPath = [Environment]::GetFolderPath("Desktop")
Copy-Item -Path $sourcePath -Destination $desktopPath
$sourcePath = "C:\JRTBase\windows\JRTBrowser-win32-ia32\JRTLogin.lnk" 
$desktopPath = [Environment]::GetFolderPath("Desktop")
Copy-Item -Path $sourcePath -Destination $desktopPath
& "C:\JRTBase\windows\JRTClient-win\JRTClient.exe"
& "C:\JRTBase\windows\JRTBrowser-win32-ia32\JRTBrowser.exe"
Remove-Item -Path "C:\JRTBase\windows.zip"
Write-Host "JRT InitEnd"
Pause

linux的install脚本,windows由于可以任意运行,只要发快捷方法,就不提供本地install了

#!/bin/bash
#shell安装JRT脚本
#20240413
#zlz
#----------------------------------------------------------mypath=$(cd $(dirname ${BASH_SOURCE[0]}); pwd )
echo "当前路径:${mypath}"
#没有在线标志文件,认为是本地执行初始化脚本
if [ ! -f /usr/share/JRTBase/linux/inlinecall.flag ];thenecho "执行本地安装"echo "创建文件夹/usr/share/JRTBase"mkdir /usr/share/JRTBaseecho "创建文件夹/usr/share/JRTBase/linux"mkdir /usr/share/JRTBase/linuxecho "拷贝${mypath}/JRTBrowser-linux-x64到/usr/share/JRTBase/linux"cp -r ${mypath}/JRTBrowser-linux-x64 /usr/share/JRTBase/linuxecho "拷贝${mypath}/JRTClient-linux到/usr/share/JRTBase/linux"cp -r ${mypath}/JRTClient-linux /usr/share/JRTBase/linux
fi
#删除在线调用标识
rm /usr/share/JRTBase/linux/inlinecall.flag#初始化浏览器
echo "授权执行权限"
sudo chmod -R +777 /usr/share/JRTBase/linux/JRTBrowser-linux-x64/*
echo "创建快捷方式到/usr/share/applications/JRTBrowser.desktop"
sudo cp /usr/share/JRTBase/linux/JRTBrowser-linux-x64/resources/app/JRTBrowser.desktop /usr/share/applications/
echo "授权快捷方式"
sudo chmod +777 /usr/share/applications/JRTBrowser.desktop
echo "让沙箱属于root"
sudo chown -R root:root /usr/share/JRTBase/linux/JRTBrowser-linux-x64/chrome-sandbox
echo "设置沙箱权限"
sudo chmod 4755 /usr/share/JRTBase/linux/JRTBrowser-linux-x64/chrome-sandbox
#给每个用户拷贝快捷方式
desk=`cat $HOME/.config/user-dirs.dirs | grep DESKTOP | tail  -1  |cut -d '=' -f 2  | sed 's/\"//g'`
var=`eval echo $desk`
echo $var
cd $var
sudo cp /usr/share/JRTBase/linux/JRTBrowser-linux-x64/resources/app/JRTBrowser.desktop $var/
echo "授权快捷方式"
sudo chmod +777 $var/JRTBrowser.desktop#初始化打印导出客户端
echo "授权执行权限"
sudo chmod -R +777 /usr/share/JRTBase/linux/JRTClient-linux/*
echo "创建快捷方式到/usr/share/applications/JRTClient.desktop"
sudo cp /usr/share/JRTBase/linux/JRTClient-linux/app/lib/JRTBrowser.desktop /usr/share/applications/
echo "授权快捷方式"
sudo chmod +777 /usr/share/applications/JRTClient.desktop
#给每个用户拷贝快捷方式
desk=`cat $HOME/.config/user-dirs.dirs | grep DESKTOP | tail  -1  |cut -d '=' -f 2  | sed 's/\"//g'`
var=`eval echo $desk`
echo $var
cd $var
sudo cp /usr/share/JRTBase/linux/JRTClient-linux/app/lib/JRTClient.desktop $var/
echo "授权快捷方式"
sudo chmod +777 $var/JRTClient.desktopecho "初始化JRT客户端环境完成"

环境下载页后台实现

import JRT.Core.MultiPlatform.JRTContext;
import JRT.Core.Util.DirUtil;
import JRT.Core.Util.TxtUtil;
import JRTBLLBase.BaseHttpHandlerNoSession;
import JRTBLLBase.Helper;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;/*** 生成Linux和Windows下初始化环境的脚本,供用户用脚本初始化环境,环境下载页面初始化时候调用此逻辑检查并且生效初始化脚本*/
public class ashDownLoad extends BaseHttpHandlerNoSession {/*** 是否正在压缩文件*/private static boolean iszip = false;/*** 得到所有能下载的文件数据** @return* @throws Exception*/public String GetAllDataFiles() throws Exception {String basePath = Paths.get(JRTContext.WebBasePath, "download", "data").toString();File base = new File(basePath);List<File> allFile = new ArrayList<>();SeeFile(base, allFile);List<String> retList = new ArrayList<>();if (allFile != null && allFile.size() > 0) {for (File f : allFile) {retList.add(f.getName());}}return Helper.Object2Json(retList);}/*** 尝试生成初始化脚本** @return*/public String TryMakeInitScript() throws Exception {String RootPath = Helper.ValidParam(JRT.Core.MultiPlatform.JRTContext.GetRequest(Request, "RootPath"), "");//处理所有客户端程序存放目录String basePath = Paths.get(JRTContext.WebBasePath, "download", "client").toString();//存下载程序的临时目录,所有文件加上.jrt后缀,防止各种类型太多mime限制String basePathTmp = Paths.get(JRTContext.WebBasePath, "download", "clienttmp").toString();//文件下载目录,最后生成初始化脚本让人下载用String dataPath = Paths.get(JRTContext.WebBasePath, "download", "data").toString();File linuxZip = Paths.get(basePathTmp, "linux.zip").toFile();File windowsZip = Paths.get(basePathTmp, "windows.zip").toFile();File base = new File(basePath);List<File> allFile = new ArrayList<>();SeeFile(base, allFile);//是否需要构造新的初始化脚本boolean needMakeNewInit = false;//压缩文件不存在就需要更新if (!linuxZip.exists() || !windowsZip.exists()) {needMakeNewInit = true;} else {//检查并且拷贝文件,生成下载用的临时文件if (allFile != null && allFile.size() > 0) {for (File f : allFile) {if (f.lastModified() > linuxZip.lastModified() || f.lastModified() > windowsZip.lastModified()) {needMakeNewInit = true;}}}}//下载页面后台data文件夹没有下载脚本就生成File winInit = Paths.get(dataPath, "windowsinitjrt.ps1").toFile();File linuxInit = Paths.get(dataPath, "linuxinitjrt.sh").toFile();//构造初始化脚本if (needMakeNewInit == true || ((!winInit.exists()) || (!linuxInit.exists()))) {System.out.println("开始压缩");if (iszip != true) {iszip = true;try {//压缩linux文件ZipFolder(Paths.get(basePath, "linux").toFile(), linuxZip);//压缩windows文件ZipFolder(Paths.get(basePath, "windows").toFile(), windowsZip);System.out.println("压缩完成");StringBuilder winSB = new StringBuilder();//构造powershell脚本AddOneWinDownload(RootPath + "/download/clienttmp/windows.zip", "windows.zip", "", winSB);//读取win模板命令String winCmd = TxtUtil.ReadTextStr(Paths.get(basePath, "windowsinitjrt.ps1").toString());//替换占位符winCmd = winCmd.replace("${initfile}", winSB.toString());//把命令写入下载地址TxtUtil.WriteText2File(Paths.get(dataPath, "windowsinitjrt.ps1").toFile(), winCmd);StringBuilder liSB = new StringBuilder();//构造sh脚本AddOneLinDownload(RootPath + "/download/clienttmp/linux.zip", "linux.zip", "", liSB);//读取linux模板命令String linuxCmd = TxtUtil.ReadTextStr(Paths.get(basePath, "linuxinitjrt.sh").toString());//替换占位符linuxCmd = linuxCmd.replace("${initfile}", liSB.toString());//把命令写入下载地址TxtUtil.WriteText2File(Paths.get(dataPath, "linuxinitjrt.sh").toString(), linuxCmd);} finally {iszip = false;}}}return Helper.Success();}/*** 构造Windows下载脚本** @param url             路径* @param fileName        文件名* @param remoteAddrLocal 相对路径* @param sb              字符串*/private void AddOneWinDownload(String url, String fileName, String remoteAddrLocal, StringBuilder sb) {fileName = fileName.replace(".jrt", "");//下载路径sb.append("$url = \"" + url + "\" " + "\r\n");//本地路径sb.append("$localFolder = \"C:\\JRTBase\\" + remoteAddrLocal.replace("/", "\\") + "\" " + "\r\n");//本地文件名sb.append("$localFileName = \"" + fileName + "\" " + "\r\n");//拼接路径sb.append("$localFile = Join-Path $localFolder $localFileName" + "\r\n");//尝试创建目录sb.append("if (!(Test-Path -Path $localFolder -PathType Container)) {  " + "\r\n");sb.append("    New-Item -ItemType Directory -Path $localFolder -Force | Out-Null " + "\r\n");sb.append("} " + "\r\n");//不显示现在进度sb.append("$ProgressPreference = 'SilentlyContinue'\n" + "\r\n");//执行下载sb.append("Invoke-WebRequest -Uri $url -OutFile $localFile" + "\r\n");}/*** 构造linux下载脚本** @param url             路径* @param fileName        文件名* @param remoteAddrLocal 相对路径* @param sb              字符串*/private void AddOneLinDownload(String url, String fileName, String remoteAddrLocal, StringBuilder sb) {fileName = fileName.replace(".jrt", "");//创建目录sb.append("mkdir -p /usr/share/JRTBase/" + remoteAddrLocal.replace("\\", "/") + " " + "\n");//删除老文件sb.append("rm -y /usr/share/JRTBase/" + remoteAddrLocal.replace("\\", "/") + fileName + " " + "\n");//下载新文件sb.append("curl " + url + " -o /usr/share/JRTBase/" + remoteAddrLocal.replace("\\", "/") + fileName + "\n");}/*** 要压缩的目录** @param folderToZip 路径* @param zipFile     输出文件名* @throws Exception*/public static void ZipFolder(File folderToZip, File zipFile) throws Exception {FileOutputStream fos = new FileOutputStream(zipFile);ZipOutputStream zos = new ZipOutputStream(fos);ZipFile(folderToZip, folderToZip.getName(), zos);zos.close();fos.close();}/*** 压缩文件** @param fileToZip 要压缩的文件* @param fileName  文件名* @param zos       输出流* @throws Exception*/private static void ZipFile(File fileToZip, String fileName, ZipOutputStream zos) throws Exception {if (fileToZip.isHidden()) {return;}if (fileToZip.isDirectory()) {if (fileName.endsWith("/")) {zos.putNextEntry(new ZipEntry(fileName));zos.closeEntry();} else {zos.putNextEntry(new ZipEntry(fileName + "/"));zos.closeEntry();}File[] children = fileToZip.listFiles();for (File childFile : children) {ZipFile(childFile, fileName + "/" + childFile.getName(), zos);}return;}FileInputStream fis = new FileInputStream(fileToZip);ZipEntry zipEntry = new ZipEntry(fileName);zos.putNextEntry(zipEntry);byte[] bytes = new byte[1024];int length;while ((length = fis.read(bytes)) >= 0) {zos.write(bytes, 0, length);}fis.close();zos.closeEntry();}/*** 扫描文件** @param dir* @param paths*/private static void SeeFile(File dir, List<File> paths) {File[] files = dir.listFiles();if (files != null) {for (File file : files) {if (file.isDirectory()) {SeeFile(file, paths);} else {paths.add(file);}}}}
}

页面代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/><title>JRT环境下载页</title><link rel="shortcut icon" href="../../resource/common/images/favicon.ico"/><script src="../../resource/common/js/JRTBSBase.js" type="text/javascript"></script><script src="../../jrtprint/js/JRTPrint.js" type="text/javascript"></script><script type="text/javascript">var me = {//文件数组fileArray: []};//初始化入口$(function () {$.messager.progress({ text: TranslateDataMTHD("prepare download data,please wait","正在构造下载数据,第一次会比较慢,请耐心等待", ""), interval: 500 });setTimeout(function () {$.messager.progress('close');}, 80000);//生成下载清单$.ajax({type: "post",dataType: "text", //text, json, xmlcache: false, //async: true, //为true时,异步,不等待后台返回值,为false时强制等待;-asirurl: '../ashx/ashDownLoad.ashx?Method=TryMakeInitScript',data: {RootPath: GetRootPath()},success: function (result, status) {//结束等待$.messager.progress('close');//渲染可以下载的文件$.ajax({type: "GET",dataType: "json", //text, json, xmlcache: false, //async: false, //为true时,异步,不等待后台返回值,为false时强制等待;-asirurl: '../ashx/ashDownLoad.ashx?Method=GetAllDataFiles',success: function (result, status) {//对数据进行筛选,是后台抛的信息的话,就提示,以及决定是否继续if (!FilterBackData(result)) {return;}if (result != null && result.length > 0) {for (var i = 0; i < result.length; i++) {if (result[i] == "linuxinitjrt.sh") {continue;}if (result[i] == "windowsinitjrt.ps1") {continue;}AddFile("../..download/data/" + result[i], result[i]);}}}});LoadFileList();}});});//得到网站根路径function GetRootPath() {var curPageUrl = window.document.location.href;var rootPath = curPageUrl.split("//")[0] + "//" + curPageUrl.split("//")[1].split("/")[0] + "//" + curPageUrl.split("//")[1].split("/")[1];return rootPath + "/";}//初步的处理数据function AddFile(url, name) {var arr = name.split(".");// 获取文件后缀,根据后缀设置图标var ext = arr[arr.length - 1];var icon = "../images/download.png";var title = arr[0];me.fileArray.push({icon: icon,url: url,name: name,title: title});}//根据me.fileArray,加载页面文件列表function LoadFileList() {for (var i = 0; i < me.fileArray.length; i++) {var file = me.fileArray[i];var box = $("<a></a>");box.attr({class: "easyui-tooltip file_item",title: file.title,href: file.url,target: "_blank",});var img = $("<img/>");img.attr({src: file.icon,class: "file_icon",});var name = $("<div></div>");name.attr({class: "file_text",});name.text(file.name);box.append(img);box.append(name);$("#panel_Main").append(box);}}</script><style>.fileDiv {display: flex;flex-wrap: wrap;padding: 0 20px 36px 20px;}.fileDiv .file_item {display: flex;margin-right: 20px;height: 20px;margin-top: 20px;line-height: 20px;cursor: pointer;}.fileDiv .file_text {margin-left: 5px;color: #0670c6;width: 140px;overflow: hidden;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 1;}.fileDiv .file_icon {width: 20px;height: 20px;}</style>
</head>
<body>
<div class="easyui-layout" fit="true"><div region="north" split="false" border="0" style="padding:10px;height:80px;"><div>欢迎使用JRT环境下载页,这里提供客户端所需要的环境及工具,请根据需要下载文件!</br>"linux初始化脚本"下载到linux后直接bash执行下载的脚步进行客户端环境初始化。windows初始化脚本用powershell执行,windows默认没开启执行脚本权限,用管理员打开powershell执行set-executionpolicy remotesigned开启。然后下载的脚步用powershell打开执行。对无法执行powershell的电脑直接下载window压缩包到本地解压,把客户端和浏览器快捷方式发送到桌面。对linux也可以下载压缩包到本地解压后运行目录的install.sh初始化。如果想把其他需要的软件放入下载页面让用户下载,那么把文件投入网站的download/data里即可。</div></div><div region="center" split="true" title="&nbsp&nbsp&nbsp环境以及工具下载"><div id="panel_Main" class="fileDiv"><a class="easyui-tooltip file_item" title="linux初始化脚本" href="../data/linuxinitjrt.sh" target="_blank"><imgsrc="../images/download.png" class="file_icon"><div class="file_text">linux初始化脚本</div></a><a class="easyui-tooltip file_item" title="windows初始化脚本" href="../data/windowsinitjrt.ps1"target="_blank"><img src="../images/download.png" class="file_icon"><div class="file_text">windows初始化脚本</div></a><a class="easyui-tooltip file_item" title="linux程序包" href="../clienttmp/linux.zip" target="_blank"><imgsrc="../images/download.png" class="file_icon"><div class="file_text">linux压缩包</div></a><a class="easyui-tooltip file_item" title="windows程序包" href="../clienttmp/windows.zip" target="_blank"><imgsrc="../images/download.png" class="file_icon"><div class="file_text">windows压缩包</div></a><a class="easyui-tooltip file_item" title="老版本谷歌安装包" href="../data/41.0.2272.101_chrome_installer.exe"target="_blank"><img src="../images/download.png" class="file_icon"><div class="file_text">谷歌浏览器下载</div></a><a class="easyui-tooltip file_item" title="新版本谷歌安装包" href="../data/chrome_installernew.exe" target="_blank"><imgsrc="../images/download.png" class="file_icon"><div class="file_text">新谷歌浏览器下载</div></a></div></div>
</div>
</body>
</html>

这样就基本完成windows和linux的环境初始化设计,JRT从构想、到demo、到雏形、到1.0发布、到正式用水准推进。

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

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

相关文章

软件开发安全备受重视,浙江某运营商引入CWASP认证课程,

​浙江省某大型运营商是一家实力雄厚、服务优质的通信运营商&#xff0c;致力于为全省用户提供优质、高效的通信服务。数字时代&#xff0c;该运营商顺应信息能量融合发展趋势&#xff0c;系统打造以5G、算力网络、能力中台为重点的新型信息基础设施&#xff0c;夯实产业转型升…

idea keymap用eclipse的相关快捷键

idea快捷键用eclipse的方式 CtrlShiftR 搜索文件 shiftshift 全部文件/类搜索 CtrlH 全局搜索 CtrlO 快速打开Outline大纲视图 ctrle 查看recent窗口文件 ctrlt 快速进入接口的实现类 ctrlshiftf 格式化代码 altshiftr 变量或函数的重命名 ctrlshifto 移除无用的头文…

C/C++内存泄漏及检测

“该死系统存在内存泄漏问题”&#xff0c;项目中由于各方面因素&#xff0c;总是有人抱怨存在内存泄漏&#xff0c;系统长时间运行之后&#xff0c;可用内存越来越少&#xff0c;甚至导致了某些服务失败。内存泄漏是最难发现的常见错误之一&#xff0c;因为除非用完内存或调用…

【LeetCode】二叉树类题目详解

二叉树 二叉树的理论基础 二叉树是结点的度数之和不超过2的树&#xff0c;二叉树总共有五种基本形态 二叉树的种类主要有&#xff1a; 满二叉树完全二叉树 二叉树的存储方式 顺序存储链式存储 二叉树的遍历方式 先序遍历&#xff08;深度优先搜索&#xff09;中序遍历&…

Python单元测试pytest捕获日志输出

使用pytest进行单元测试时&#xff0c;遇到了需要测试日志输出的情况&#xff0c;查看了文档 https://docs.pytest.org/en/latest/how-to/capture-stdout-stderr.html https://docs.pytest.org/en/latest/how-to/logging.html 然后试了一下&#xff0c;捕捉logger.info可以用…

微信小程序 uniapp+vue.js医疗在线问诊挂号系统4oy17

预约挂号系统的逐渐发展&#xff0c;进一步方便了广大用户&#xff0c;使其可以更方便、快捷地预约挂号&#xff0c;并且也有效地防止号贩子“倒号”&#xff0c;使用户预约挂号更公平&#xff0c;然而现有预约挂号系统或多或少有所欠缺 小程序前端框架&#xff1a;uniapp 小程…

7、configMap

1、configMap是什么 类似与pod的配置中心&#xff0c;不会因为pod的创建销毁&#xff0c;相关配置发生改变 pod定义硬编码意味着需要有效区分⽣产环境与开发过程中的pod 定义。为了能在多个环境下复⽤pod的定义&#xff0c;需要将配置从pod定义描 述中解耦出来。 2、向容器中…

python-study-day2

pycharm注释(也可修改) 快捷键ctrl /手敲一个 " # " 这个是单行注释""" """ 左边这个三个引号可以完成多行注释 基础知识 常用的数据类型 def hello(self):print("Hello")print(type(1)) print(type("1"…

Unity Standalone File Browser,Unity打开文件选择器

Unity Standalone File Browser&#xff0c;Unity打开文件选择器 下载地址&#xff1a;GitHub链接&#xff1a; https://github.com/gkngkc/UnityStandaloneFileBrowser简单的示例代码 using SFB; using System; using System.IO; using UnityEngine; using UnityEngine.UI;…

Redis从入门到精通(十六)多级缓存(一)Caffeine、JVM进程缓存

文章目录 第6章 多级缓存6.1 什么是多级缓存&#xff1f;6.2 搭建测试项目6.2.1 项目介绍6.2.2 新增商品表6.2.3 编写商品相关代码6.2.4 启动服务并测试6.2.5 导入商品查询页面&#xff0c;配置反向代理 6.3 JVM进程缓存6.3.1 Caffeine6.3.2 实现JVM进程缓存6.3.2.1 需求分析6.…

C语言--结构体大小

基本数据类型占用的字节数分别为:char(1),short(2),int(4),long(4),long long(8),float(4),double(8)。 分析一下下面结构体占用的字节数。 struct A { int a; }; struct B { char a; int b; }; int main() { printf("sizeof(struct A)%d\n", sizeof(struct A));//测…

BI数据分析软件:行业趋势与功能特点剖析

随着数据量的爆炸性增长&#xff0c;企业对于数据的需求也日益迫切。BI数据分析软件作为帮助企业实现数据驱动决策的关键工具&#xff0c;在当前的商业环境中扮演着不可或缺的角色。本文将从行业趋势、功能特点以及适用场景等方面&#xff0c;深入剖析BI数据分析软件&#xff0…

Docker容器tomcat中文名文件404错误不一定是URIEncoding,有可能是LANG=zh_CN.UTF-8引起

使用Docker部署tomcat&#xff0c;出现中文名文件无法读取&#xff0c;访问就是404错误。在网上搜索一通&#xff0c;都说是在tomcat的配置文件server.xml中修改一下URIEncoding为utf-8就行&#xff0c;但是我怎么测试都不行。最终发现&#xff0c;是Docker启动时&#xff0c;传…

关于Excel中自动填充的功能,看这篇文章就差不多了

序言 这篇文章介绍了Excel的自动填充功能。你将学习如何在Excel 365、2021、2019、2016、2013及更低版本中填充一系列数字、日期和其他数据,创建和使用自定义列表。这篇文章还让你确保你知道关于填充柄的一切,因为你可能会惊讶于这个小选项的强大。 当时间紧迫时,每一分钟…

(二)ffmpeg 下载安装以及拉流推流示例

一、ffmpeg下载安装 官网&#xff1a;https://www.ffmpeg.org/ 源码下载地址&#xff1a;https://www.ffmpeg.org/download.html#releases 下载源码压缩包 下载完成之后解压并在该目录下打开命令窗口 安装依赖环境&#xff1a; sudo apt-get install build-essential nasm …

防火墙操作!

当小编在Linux服务器上部署好程序以后&#xff0c;但是输入URL出现下述情况&#xff0c;原来是防火墙的原因&#xff01;&#xff01; 下面是一些防火墙操作&#xff01; 为保证系统安全&#xff0c;服务器的防火墙不建议关闭&#xff01;&#xff01; 但是&#xff0c;我们可…

麒麟 V10 离线 安装 k8s 和kuboard

目录 安装文件准备 主机准备 主机配置 修改主机名&#xff08;三个节点分别执行&#xff09; 配置hosts&#xff08;所有节点&#xff09; 关闭防火墙、selinux、swap、dnsmasq(所有节点) 安装依赖包&#xff08;所有节点&#xff09; 系统参数设置(所有节点) 时间同步…

C#Winform使用扩展方法自定义富文本框(RichTextBox)字体颜色

实现效果 调用方法 rtxtLog.AppendTextColorful(richTextBox1,DateTime.Now.ToString(), Color.Red); 完整代码如下 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using Sys…

CentOS7 boa服务器的搭建和配置

环境是CentOS7&#xff0c;但方法不局限于此版系统&#xff0c;应该是通用的。 具体步骤如下&#xff1a; 1. 下载boa源码 下载地址: Boa Webserver 下载后&#xff0c;进入压缩包所在目录&#xff0c;进行解压&#xff1a; tar xzf boa-0.94.13.tar.gz 2. 安装需要的工具b…

了解虚拟路由器冗余协议(VRRP)

虚拟路由器冗余协议&#xff08;VRRP&#xff09;是一种被广泛使用的网络协议&#xff0c;旨在增强网络的可靠性和可用性。对于网络管理员和工程师来说&#xff0c;了解VRRP是确保网络能够实现无缝故障转移和保持不间断连接的关键。本文将深入探讨VRRP的基础知识&#xff0c;包…