文件服务器FastDFS 消息队列中间件RabbitMQ
新标签页 (chinaunix.net)
FastDFS - Browse Files at SourceForge.net
一、FastDFS
Tracker和Storage:
tracker用来管理所有的storage,只是管理服务器,负责负载均衡。
storage是存储服务器,每一个storage服务器都是一个单独的个体,storage服务器之间没有交互关系。
在storage中根目录包含256个一级目录、每个一级目录中包含256个二级子目录,在二级子目录中存储图片。存储图片时服务器会返回相应的group和remote,访问文件时通过这两个键值对获取图片。
①、在虚拟机中使用docker安装FastDFS
docker load -i fastdfs.tar //在docker中加载镜像源文件mkdir -p /opt/fdfs/tracker docker run -d --network=host --name tracker -v /opt/fdfs/tracker:/var/fdfs delron/fastdfs tracker mkdir -p /opt/fdfs/storagedocker run -d --network=host --name storage -e TRACKER_SERVER=192.168.222.128:22122 -v /opt/fdfs/storage:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage//重启服务器需要删除文件。
rm -rf /opt/fdfs/tracker/data/*.pid
rm -rf /opt/fdfs/storage/data/*.pid//更改服务器的磁盘限制
docker exec -it tracker bash
cd /etc/fdfs
vi /etc/fdfs/tracker.conf
reserved_storage_space = 10K //磁盘剩余多少空间时关闭上传文件功能
②、java代码使用FastDFS
1)首先编写FastDFS配置信息fdfs.properties
fastdfs.connect_timeout_in_seconds=10 fastdfs.network_timeout_in_seconds=30 fastdfs.charset=UTF-8 # tracker???????????????? fastdfs.tracker_servers=192.168.222.128:22122 # tracker????????tracker.conf??http?????????? fastdfs.http_tracker_http_port=8080
2)FastDFS 操作工具类
封装了加载配置文件fdfs.properties的静态代码块,还有上传和下载的方法。
package com.xja.util;import org.csource.common.NameValuePair; import org.csource.fastdfs.*;import java.io.InputStream; import java.util.Properties;/*** FastDFS Java客户端工具*/ public final class FastDFSUtils {/*** 定义静态属性,Properties和StorageClient*/private final static Properties PROPERTIES;private final static StorageClient STORAGE_CLIENT;/*** 静态初始化代码块,初始化静态属性* 静态初始化代码块有异常如何处理?* 处理的时候,try。。catch。。 抛出一个Error,终止虚拟机。*/static{try {PROPERTIES = new Properties();// 读取配置文件PROPERTIES.load(FastDFSUtils.class.getClassLoader().getResourceAsStream("fdfs.properties"));// 使用ClientGlobal初始化FastDFS客户端配置ClientGlobal.initByProperties(PROPERTIES);// 创建Tracker客户端对象TrackerClient trackerClient = new TrackerClient();// 基于Tracker客户端对象,获取Tracker服务器对象TrackerServer trackerServer = trackerClient.getConnection();// 基于Tracker服务器和客户端对象,获取Storage服务器对象StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);// 创建Storage客户端对象STORAGE_CLIENT = new StorageClient(trackerServer, storageServer);}catch (Exception e){throw new ExceptionInInitializerError(e);}}/*** 删除文件* int delete_file(String 卷名, String 路径及文件名);* 返回值: 0代表成功,其他数字代表错误编码*/public static int remote(String group, String remote){try {return STORAGE_CLIENT.delete_file(group, remote);}catch (Exception e){e.printStackTrace();return -1;}}/*** 查询某文件的元数据* @param group 卷名* @param remote 路径及文件名* @return 返回文件的元数据数组。发生错误返回null*/public static NameValuePair[] getMetaData(String group, String remote){try{return STORAGE_CLIENT.get_metadata(group, remote);}catch (Exception e){e.printStackTrace();return null;}}/*** 下载文件工具方法* 下载方法* byte[] download_file(String 卷名, String 路径及文件名)* 返回要下载的文件内容* @param group 卷名* @param remote 路径及文件名* @return 返回下载的文件内容,发生错误返回null*/public static byte[] download(String group, String remote){try {return STORAGE_CLIENT.download_file(group, remote);}catch (Exception e){e.printStackTrace();return null;}}/*** 上传文件的工具方法* 一定保存文件到FastDFS,一定保存至少一个元数据(文件原始名称)* @param inputStream 要上传的文件的输入流* @param fileName 上传文件的原始名称* @param metaProperties 上传文件的元数据,成对提供,如: 名,值,名,值* @return*/public static String[] uploadFile(InputStream inputStream, String fileName, String... metaProperties){try {int length = inputStream.available();byte[] datas = new byte[length];inputStream.read(datas, 0, length);// 处理元数据NameValuePair[] nameValuePairs = null;if (metaProperties.length % 2 == 0) {// 参数数量满足要求,开始处理nameValuePairs = new NameValuePair[metaProperties.length / 2 + 1];for (int i = 0; i < nameValuePairs.length; i = i + 2) {nameValuePairs[i / 2] = new NameValuePair(metaProperties[i], metaProperties[i + 1]);}} else {nameValuePairs = new NameValuePair[1];}nameValuePairs[nameValuePairs.length - 1] = new NameValuePair("fileName", fileName);// 获取文件后缀String extName = getExtName(fileName);// 上传文件到FastDFSString[] result = STORAGE_CLIENT.upload_file(datas, extName, nameValuePairs);for (String s : result) {System.out.println("s = " + s);//s = group1//s = M00/00/00/wKjegGbqfoKACfLIAAAnJ2OoZs8411.txt}System.out.println("============= " + nameValuePairs[0]+ "/n"+ nameValuePairs[1]);//============= org.csource.common.NameValuePair@4ae28001/norg.csource.common.NameValuePair@3e472f5dreturn result;}catch (Exception e){// 发生任何异常,上传文件失败。返回nulle.printStackTrace();return null;}}/*** 截取文件后缀* @param fileName* @return*/private static String getExtName(String fileName){if(fileName.lastIndexOf(".") > -1){// 文件名称中包含字符 .return fileName.substring(fileName.lastIndexOf(".") + 1);}else{// 文件名称中不包含字符 .return "";}}/*** 提供获取Storage客户端对象的工具方法*/public static StorageClient getStorageClient(){return STORAGE_CLIENT;}private FastDFSUtils(){} }
3)编写上传和下载路由
下载路由中需要加上内容类型和响应头,否则可能出现访问下载却出现在线预览图片
@Controller public class LoginController {@RequestMapping("/index")public String uploadPage(){return "index";}@RequestMapping("/upload")public String upload(MultipartFile file, HttpSession session) throws IOException {InputStream inputStream = file.getInputStream();String originalFilename = file.getOriginalFilename();String[] strings = FastDFSUtils.uploadFile(inputStream, originalFilename, "s", "");System.out.println(strings);return "a";}@RequestMapping("/download")public void download(String group,String remote,HttpServletResponse response) throws IOException {byte[] datas = FastDFSUtils.download(group, remote);response.setContentType("application/octet-stream");// 设置下载文件的附件名称NameValuePair[] metaData = FastDFSUtils.getMetaData(group, remote);String fileName = "";for (NameValuePair metaDatum : metaData) {if ("fileName".equals(metaDatum.getName()))fileName = metaDatum.getValue();}response.setHeader("content-disposition","attachment;filename="+fileName.toString());// 输出要下载的文件内容到客户端 // byte[] datas = (byte[]) result.get("datas");response.getOutputStream().write(datas, 0, datas.length);response.getOutputStream().flush();}}
4)上传一张图片,在浏览器中访问图片
这里的端口号为8888,fastdfs中内置有nginx服务器,请求从nginx服务器转发到storage服务器.
二、RabbitMQ
publisher项目使用RabbitMQ软件将消息推送至交换机,交换机根据路由键将消息推送至相应队列中。Consumer项目中的监听器时刻监听提前设置好的监听队列,如果有消息进入队列中,会调用单元方法将消息中的数据取出消费,消费成功后返回信息在队列中删除消息
如果消息在Consumer项目中拿取数据或者消费过程中出现错误,这个时候不会被删除,而是会多次尝试再次获取 消息 消费。达到一定次数,停止尝试。
多个消费者同时监听一个消息队列时,采用轮循策略依次发送消息。
1)虚拟机使用docker安装RabbitMQ
0、docker命令:
docker pull rabbitmq:managementdocker run -d --name rabbitmq -p 15672:15672 -p 5672:5672 --restart=always -e DEFAULT_USER=wollo -e DEFAULT_PASS=wollo rabbitmq:management①、 访问 http:192.168.222.128:15672: //Docker宿主机IP:15672
这个是RabbitMQ提供的可视化界面,类似于Navicat。
②、使用可视化界面操作RabbitMQ:
创建交换机、创建队列、将交换机和队列绑定并设置路由键
2)使用java代码连接操作RabbitMQ
1.新建一个父工程统一管理springBoot的版本号
打包方式为 pom
2.新建子工程publisher、consumer 及依赖配置
两个子工程都添加springAMQP依赖。
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
publisher配置文件:
#配置RabbitMq的链接参数 spring:rabbitmq:host: 192.168.222.128 # RabbitMQ服务器的IP。默认localhostport: 5672 # RabbitMQ服务器的端口。username: wollo # RabbitMQ的访问用户名。默认guest。password: wollo # RabbitMQ的访问密码。默认guestvirtual-host: / # 连接RabbitMQ中的哪一个虚拟主机。默认 /publisher-confirm-type: correlated # 开启到达交换器确认机制。默认值:none,不开启确认机制。publisher-returns: true # 开启到达消息队列确认机制。默认值:none,不开启确认机制。
consumer:
#配置RabbitMq的链接参数 spring:rabbitmq:host: 192.168.222.128 # RabbitMQ服务器的IP。默认localhostport: 5672 # RabbitMQ服务器的端口。username: wollo # RabbitMQ的访问用户名。默认guest。password: wollo # RabbitMQ的访问密码。默认guestvirtual-host: / # 连接RabbitMQ中的哪一个虚拟主机。默认 /listener:simple:retry:enabled: true # 开启重试机制max-attempts: 3 # 重试消费1次
2.1)第一次使用Publisher发送消息,Consumer消费消息
1.前面在可视化界面中已经配置了交换机,绑定的消息队列,路由键
交换机 rk.direct
消息队列 rk.queue
路由键 route.regex
2.在publisher发送消息运行test()方法 ,别忘了编写启动类文件

3.在Consumer中接收消息,需要指定接收的消息队列,同样别忘了编写启动类

4.在运行的Consumer项目控制台中会打印"皇室"。
2.2)发送和接收一个序列化对象User
1.新建commen子模块,publisher和consumer引入该模块
commen子模块新建User类,实现Serializable接口
2.可视化界面新建交换机rk.direct1 , 消息队列rk.queue1 ,发送user对象:
publisher的测试类:

consumer的消息队列:

consumer项目控制台:

2.3)其他类型交换器 基于注解创建交换机、消息队列
1.交换机类型有四种:
direct为完全匹配路由键
fanout为广播
topic为模糊匹配
2.这里创建一个广播类型的交换机
key值任意写,因为广播针对绑定的所有消息队列。
@Component public class FanoutConsumer {@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "fanout.queue",durable = "true",autoDelete="false"),exchange = @Exchange(name = "rk.fanout",type = "fanout",durable = "true",autoDelete = "false"),key = {"route.regex"})})public void OnMessage(String messageBody){System.out.println("messageBody = " + messageBody);}}
3.topic交换机
@Component public class MyTopicConsumer {@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.1", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"小学.同学"})})public void onMessage1(String message){System.out.println("小学.同学 - " + message);}@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.2", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"小学.老师"})})public void onMessage2(String message){System.out.println("小学.老师 - " + message);}@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.3", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"小学.*"})})public void onMessage3(String message){System.out.println("小学.* - " + message);}@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.4", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"大学.老师"})})public void onMessage4(String message){System.out.println("大学.老师 - " + message);}@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.5", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"*.老师"})})public void onMessage5(String message){System.out.println("*.老师 - " + message);}@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "queue.topic.6", autoDelete = "false"),exchange = @Exchange(name = "topic.first", type = "topic"),key = {"#"})})public void onMessage6(String message){System.out.println("# - " + message);}}
2.4)消息传递失败的处理方法
①publisher推送的消息失败的回调方法
1. 开启回调方法的确认机制。
2.实现回调接口
@Component
public class PublisherHandle implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnsCallback{@Autowiredprivate RabbitTemplate rabbitTemplate;@PostConstructpublic void init(){this.rabbitTemplate.setConfirmCallback(this);this.rabbitTemplate.setReturnsCallback(this);}@Overridepublic void confirm(CorrelationData correlationData, boolean b, String s) {System.out.println("到达交换机:"+b);}/*** @description:* System.out.println( 交换器 : returnedMessage.getExchange ());* System.out.println("路由键 : " + returnedMessage.getRoutingKey());* System.out.println("路由失败编码 : " + returnedMessage.getReplyCode());* System.out.println("路由失败描述 : " + returnedMessage.getReplyText());* System.out.println("消息 : " + returnedMessage.getMessage());* @author:rk* @date: 2024/9/24 10:47* @param: returnedMessage**/@Overridepublic void returnedMessage(ReturnedMessage returnedMessage) {System.out.println("到达消息队列:"+returnedMessage.getReplyCode());}
}
②consumer
配置中设置重试次数、或者开启手工ACK方式解决消息处理失败问题

2.5)手动发送确认ACK
1.配置开启手工确认
2. 创建交换机、消息队列并设置手工ACK
@Component
public class MyAckConsumer {//测试消费的ACK:@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "ack.queue"),exchange = @Exchange(name = "ack.direct"),key = {"ack.routing"})})public void testAckMessage(String message, Channel channel,@Header(AmqpHeaders.DELIVERY_TAG)Long deliveryTag) throws Exception {System.out.println("消息消费:"+message+"---"+deliveryTag);//主动通知RabbitMq消息被正确消费,RabbitMq会将消息从队列中移除//channel.basicAck(deliveryTag, false);//主动通知RabbitMq消息没有被正确消费(消息的ID,消费结果,是否重试消费false表示删除消息true表示重复消费)//channel.basicNack(deliveryTag,false,true);//主动通知RabbitMq消息没有消费,直接丢弃(消息的ID,false表示删除消息true表示尝试重复消费),丢失一般是在消息消费的代码之前channel.basicReject(deliveryTag, false);}
}
2.6)同步消息处理
1.配置同步时长

2.消费者代码
@Component
public class SynchronizationMessageConsumer {@RabbitListener(bindings = {@QueueBinding(value = @Queue(name = "return.queue"),exchange = @Exchange(name = "return.direct"),key = {"return.routing"})})public String testAckMessage(String message , Channel channel, @Header(AmqpHeaders.DELIVERY_TAG)Long deliveryTag) throws Exception {System.out.println("消息的消费内容为:"+message);return "今天天气不错,适合学习";}
}
3.推送者代码:

4.测试

相关文章:
文件服务器FastDFS 消息队列中间件RabbitMQ
新标签页 (chinaunix.net) FastDFS - Browse Files at SourceForge.net 一、FastDFS Tracker和Storage: tracker用来管理所有的storage,只是管理服务器,负责负载均衡。 storage是存储服务器,每一个storage服务器都是一个单独的个…...
工作纪实58-Idea打jar包
有时候需要配合算法使用spark定时DP,调用java相关的jar包做数据处理 idea打jar包有以下三种场景 SpringBoot的Maven项目【Maven打包即可】非SpringBoot的Maven项目【添加maven打包参数,使用Maven打包】 借助maven的配置进行打包,新增以下配置…...
ELK-03-skywalking监控linux系统
文章目录 前言一、下载node_exporter二、启动node_exporter三、下载OpenTelemetry Collector四、启动OpenTelemetry Collector4.1 将配置文件下载到同级目录4.2 启动 五、查看总结 前言 skywalking安装完成后,开始我们的第一个监控-监控linux系统。 参考官方文档&a…...
HEITRONICS TC13红外辐射高温计CT13 INFRARED RADIATION PYROMETER CT13
HEITRONICS TC13红外辐射高温计CT13 INFRARED RADIATION PYROMETER CT13...
开源图像降噪算法与项目介绍【持续更新】
Intel Open Image Denoise 介绍:Intel Open Image Denoise(OIDN)是一个开源库,它提供了一系列高性能、高质量的去噪滤镜,专门用于光线追踪渲染的图像。这个库是Intel Rendering Toolkit的一部分,并且是在宽…...
RealSense、ZED 和奥比中光Astra几款主流相机介绍及应用
以下是英特尔 RealSense、Stereolabs ZED 和奥比中光Astra几款相机的详细对比,包括参数、性能以及二次开发等支持,附带代码示例。 详细信息对比和二次开发示例 1. 英特尔 RealSense (例如 D435/D455) 深度技术:立体视觉 红外投影分辨率&a…...
启动 Ntopng 服务前需先启动 redis 服务及 Ntopng 常用参数介绍
启动Ntopng服务之前需要先启动redis服务,因为Ntopng服务依赖于redis服务的键值存储。 服务重启 服务启动 Ntopng常用参数: -d 将 Ntopng 进程放入后台执行。默认情况下,Ntop 在前台运行。 -u 指定启动Ntopng执行的用户,默认为…...
vector的模拟实现以及oj题(2)
前言 上篇博客介绍了大部分vector的接口,其中包括begin()、end()、const begin()、 const end()、size、capacity、reserve、empty、push_back、pop_back、insert、operator[],这篇博客将介绍剩下的部分接口,以及一些oj题解法和思路。 vect…...
数据技术进化史:从数据仓库到数据中台再到数据飞轮的旅程
随着大数据时代的到来,数据已经成为企业的核心资产之一。在过去几十年间,数据技术也随之不断演进,从早期的数据仓库到近年来热门的数据中台,再到正在快速发展的数据飞轮概念,每一步都是技术革新的体现。 一、数据仓库&…...
JAVA JDK华为云镜像下载,速度很快
直达下载地址 https://repo.huaweicloud.com/java/jdk/ https://repo.huaweicloud.com/java/jdk/欢迎各位收藏享用!!!...
【RKNN系列】官方函数:querystring
querystring 函数 功能 查询获取当前芯片平台RGA硬件版本与功能支持信息,以字符串的形式返回。 语法 std::string querystring(int query_type);参数 query_type: 要查询的 RGA 信息类型(整数) 描述 这个函数用于获取特定类型的 RGA 信…...
Stable Diffusion零基础学习
Stable Diffusion学习笔记TOP14 _插件篇之ControlNet功能篇 ControlNet目前支持的10多种预处理器,根据数据检测种类可分为两种类型: 1、功能型:拥有着不同的能力 2、构图型:控制着SD扩散图形的构图规则 部分未编写预处理器的功…...
C#基于SkiaSharp实现印章管理(9)
将印章设计模块设计的印章保存为图片并集中存放在指定文件夹内。新建印章应用项目,主要实现对图片及PDF文件加盖印章功能。本文实现给图片加盖印章功能。 给图片加盖印章的逻辑比较简单,就是将印章图片绘制到图片指定位置,使用SKControl控…...
研究生如何利用ChatGPT帮助开展日常科研工作?
小白可做!全自动AI影视解说一键成片剪辑工具https://docs.qq.com/doc/DYnl6d0FLdHp0V2ll 作为当代研究生,科研工作三部曲----读文献、开组会、数据分析。无论哪一个,都令研究生们倍感头疼,简直就是梦魇。每当看到导师发来的消息&a…...
汽车零部件开发流程关键阶段
目录 1、定点阶段 1.1、定点前的准备工作 1.2、定点决策过程 1.3、定点后的工作交接 2、A样阶段:设计验证与基本功能实现 2.1、样件制作:从设计图纸到实物转化 2.2、功能测试:初步验证与性能评估 2.3、评估与优化:A样阶段…...
Magnific推V2图像生成服务 可直出4K图像
人工智能 - Ai工具集 - 集合全球ai人工智能软件的工具箱网站 近日,AI图像处理领域再迎重大突破,Magnific推出的V2图像生成服务引领行业潮流。此次升级,不仅使Magnific从高端软件跻身为顶级AI图像生成器,更彰显了其在技术创新及用…...
E9OA解决文档附件没有关联文档正文问题
业务背景: OA通知流程已经提交后在审批中发现漏上传了文档附件。临时放开审批结点文档附件编辑,请审批结点领导将附件上传后再审批。最终在流程中查看可以看到正文和附件,但是在通知文档正文中没有关联文档附件,导致大多数人员在通…...
EasyExcel日常使用总结
文章目录 概要引入依赖常用操作方法折叠或隐藏列折叠或隐藏行单元格样式单行表头设置多行表头设置多个sheet写入自动列宽 概要 EasyExcel日常使用总结。 引入依赖 引入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</a…...
人只活一次,活出一道光吧
人只活一次, 你怎么舍得让自己的短暂的一生是丑陋的, 你怎么舍得让自己短暂的一生, 只是在往下坠落, 即便是坠落, 也应该具有落日般的华丽吧, 你会漫漫的活成一束光, 谁若接近你, 就是接近光, 【人人都想向上,人人都想老而不衰,但现实是当你想活成一道光…...
sqli-labs:1~16(sql注入点稳定判断语句、全回显半回显报错回显无回显利用思路、sql注入tips)
怎么验证sql注入的存在呢? 首先,双引号单引号注入,看看有没有报错,或者与正常参数的区别,有报错说明大概率可以注入成功,但是,很可能单引号和双引号测试可能没有报错回显,或者与正常…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
















