【消息队列开发】 实现内存加载

文章目录

  • 🍃前言
  • 🌳实现思路
    • 🚩读取消息长度
    • 🚩读取相应长度的消息
    • 🚩进行反序列化
    • 🚩判定是否有效
    • 🚩加入有效消息
    • 🚩收尾工作
    • 🚩代码实现
  • ⭕总结

🍃前言

本次开发目标实现内存加载

我们在硬盘与内存中都存入了我们的消息,但是呢,当程序重启后,内存中的消息就会丢失,这时候我们就需要将硬盘中的数据写入内存中

🌳实现思路

首先我们定义两个变量

一个是使用一个LinkedList的数组接收硬盘里面存储的数据。

除此之外我们还定义一个变量currentOffset用来记录我们读写文件的光标

接下来我们开始进行实现,分为5步实现

🚩读取消息长度

根据我们定义存入硬盘的消息结构

先读取最前面的四个字节,这四个字节里面的内容代表的是整个消息的长度
在这里插入图片描述

🚩读取相应长度的消息

构造相应长度的字节数组,进行读取

并且进行判断,实际读取消息的长度是否符合

若不符合,我们需要抛出我们自定义的异常
在这里插入图片描述

🚩进行反序列化

在这里插入图片描述

🚩判定是否有效

我们需要对反序列化后的对象进行判断

若该Message对象已近无效,那么我们就可以直接跳过了

需要注意的是,这时候我们也需要将我们的currentOffset变量进行更新

在这里插入图片描述

🚩加入有效消息

若为有效数据, 则需要把这个 Message 对象加入到链表中. 加入之前还需要填写 offsetBeg 和 offsetEnd

进行计算 offset 的时候, 需要知道当前文件光标的位置的.

而我们的currentOffset变量正记录着我们当前的位置
在这里插入图片描述

🚩收尾工作

由于我们不知道消息有多长,所以我们将上述操作放入一个while(true)的循环里进行读取

但是呢,我们应该怎么判断是否读取结束呢?

其实我们使用读取四个字节的方法readInt()

当后面没有数据时,它便会抛出异常,这里我们利用这个抛出的异常,我们在最后进行捕获,但是呢。

这个抛出的“异常”其实是一个正常的数据

🚩代码实现

// 使用这个方法, 从文件中, 读取出所有的消息内容, 加载到内存中(具体来说是放到一个链表里)
// 这个方法, 准备在程序启动的时候, 进行调用.
// 这里使用一个 LinkedList, 主要目的是为了后续进行头删操作.
// 这个方法的参数, 只是一个 queueName 而不是 MSGQueue 对象. 因为这个方法不需要加锁, 只使用 queueName 就够了.
// 由于该方法是在程序启动时调用, 此时服务器还不能处理请求呢~~ 不涉及多线程操作文件.
public LinkedList<Message> loadAllMessageFromQueue(String queueName) throws IOException, MqException, ClassNotFoundException {
    LinkedList<Message> messages = new LinkedList<>();
    try (InputStream inputStream = new FileInputStream(getQueueDataPath(queueName))) {
        try (DataInputStream dataInputStream = new DataInputStream(inputStream)) {
            // 这个变量记录当前文件光标.
            long currentOffset = 0;
            // 一个文件中包含了很多消息, 此处势必要循环读取.
            while (true) {
                // 1. 读取当前消息的长度, 这里的 readInt 可能会读到文件的末尾(EOF)
                //    readInt 方法, 读到文件末尾, 会抛出 EOFException 异常. 这一点和之前的很多流对象不太一样.
                int messageSize = dataInputStream.readInt();
                // 2. 按照这个长度, 读取消息内容
                byte[] buffer = new byte[messageSize];
                int actualSize = dataInputStream.read(buffer);
                if (messageSize != actualSize) {
                    // 如果不匹配, 说明文件有问题, 格式错乱了!!
                    throw new MqException("[MessageFileManager] 文件格式错误! queueName=" + queueName);
                }
                // 3. 把这个读到的二进制数据, 反序列化回 Message 对象
                Message message = (Message) BinaryTool.fromBytes(buffer);
                // 4. 判定一下看看这个消息对象, 是不是无效对象.
                if (message.getIsValid() != 0x1) {
                    // 无效数据, 直接跳过.
                    // 虽然消息是无效数据, 但是 offset 不要忘记更新.
                    currentOffset += (4 + messageSize);
                    continue;
                }
                // 5. 有效数据, 则需要把这个 Message 对象加入到链表中. 加入之前还需要填写 offsetBeg 和 offsetEnd
                //    进行计算 offset 的时候, 需要知道当前文件光标的位置的. 由于当下使用的 DataInputStream 并不方便直接获取到文件光标位置
                //    因此就需要手动计算下文件光标.
                message.setOffsetBeg(currentOffset + 4);
                message.setOffsetEnd(currentOffset + 4 + messageSize);
                currentOffset += (4 + messageSize);
                messages.add(message);
            }
        } catch (EOFException e) {
            // 这个 catch 并非真是处理 "异常", 而是处理 "正常" 的业务逻辑. 文件读到末尾, 会被 readInt 抛出该异常.
            // 这个 catch 语句中也不需要做啥特殊的事情
            System.out.println("[MessageFileManager] 恢复 Message 数据完成!");
        }
    }
    return messages;
}

⭕总结

关于《【消息队列开发】 实现内存加载》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序基础面试题

1、简述微信小程序原理 小程序本质就是一个单页面应用&#xff0c;所有的页面渲染和事件处理&#xff0c;都在一个页面内进行&#xff0c;但又可以通过微信客户端调用原生的各种接口&#xff1b;它的架构&#xff0c;是数据驱动的架构模式&#xff0c;它的UI和数据是分离的&am…

【UE5】动画混合空间的基本用法

项目资源文末百度网盘自取 什么是动画混合空间 混合空间分为两种: 通过一个数值控制通过两个数值控制 下面通过演示让大家更直观地了解 在Character文件夹中单击右键,选择动画(Animation),选择旧有的混合空间1D 然后选择骨骼&#xff08;动画是基于骨骼显示的,所以需要选择…

杂七杂八111

MQ 用处 一、异步。可提高性能和吞吐量 二、解耦 三、削峰 四、可靠。常用消息队列可以保证消息不丢失、不重复消费、消息顺序、消息幂等 选型 一Kafak:吞吐量最大&#xff0c;性能最好&#xff0c;集群高可用。缺点&#xff1a;会丢数据&#xff0c;功能较单一。 二Ra…

构建用户身份基础设施,推动新能源汽车高质量发展

随着市场进入智能电动汽车时代&#xff0c;车企们发现&#xff0c;在激烈竞争的市场中不断增长&#xff0c;并不是一件容易的事。《麻省理工科技评论》&#xff0c;前段时间写了一篇报道&#xff1a;中国是如何称霸电动汽车世界的&#xff1f;“过去两年&#xff0c;中国电动汽…

项目性能优化—性能优化的指标、目标

项目性能优化—性能优化的指标、目标 性能优化的终极目标是什么 性能优化的目标实际上是为了更好的用户体验&#xff1a; 一般我们认为用户体验是下面的公式&#xff1a; 用户体验 产品设计&#xff08;非技术&#xff09; 系统性能 ≈ 系统性能 快 那什么样的体验叫快呢…

定力至上,穿越周期——哪吒汽车闯进国际大市场

近年来&#xff0c;全球气候变化和环境保护议题日益受到关注&#xff0c;环保意识逐渐深入人心。在这一背景下&#xff0c;新能源汽车作为一种低碳、环保的交通工具受到了广泛关注和青睐。各国纷纷加大对新能源汽车产业的支持力度&#xff0c;通过出台补贴政策、购车优惠以及充…

Linux学习之网络

目录 认识协议 网络协议初始 协议分层 OSI七层模型 TCP/IP的四层模型 数据包封装和分用 以太网通信 ip地址与MAC地址 网络编程套接字 端口号&#xff08;port&#xff09; 认识协议 网络字节序 socket接口 网络的产生是计算机历史的必然性&#xff0c;是计算机发展…

【闲聊】-后端框架发展史

框架&#xff0c;是为了解决系统复杂性&#xff0c;提升开发效率而产生的工具&#xff0c;主要服务于研发人员。 当然&#xff0c;框架还有更深层的作用&#xff0c;框架的沉淀是一种高级的抽象&#xff0c;会将人类的业务逐步抽象为统一标准又灵活可变的结构&#xff0c;为各行…

暴雨高性能分布式存储为AI提供坚实数据存力

随着两会的圆满落幕&#xff0c;新质生产力和人工智能的发展成为社会各界热议的焦点。总理在两会后的首次调研中&#xff0c;特别强调了新质生产力和人工智能的重要性&#xff0c;这无疑为人工智能产业的蓬勃发展注入了新的动力。 年初&#xff0c;Sora所引领的人工智能热潮更…

安卓百度地图API显示隐藏Marker

方法 BaiduMap.Marker.setVisible(boolean) 实现 List<Marker> list_marker new ArrayList<>(); boolean isShowMarker true;Override public boolean onCreateOptionsMenu(Menu menu) {String[] sm { "显隐信息", "显隐照片", "截…

YOLOv8_seg-Openvino和ONNXRuntime推理【CPU】

纯检测系列&#xff1a; YOLOv5-Openvino和ONNXRuntime推理【CPU】 YOLOv6-Openvino和ONNXRuntime推理【CPU】 YOLOv8-Openvino和ONNXRuntime推理【CPU】 YOLOv7-Openvino和ONNXRuntime推理【CPU】 YOLOv9-Openvino和ONNXRuntime推理【CPU】 跟踪系列&#xff1a; YOLOv5/6/7-O…

(二十五)Flask之MTVMVC架构模式Demo【重点:原生session使用及易错点!】

目录&#xff1a; 每篇前言&#xff1a;MTV&MVC构建一个基于MTV模式的Demo项目&#xff1a;蹦出一个问题&#xff1a; 每篇前言&#xff1a; &#x1f3c6;&#x1f3c6;作者介绍&#xff1a;【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领…

VScode 关闭鼠标悬停提示

设置-文本编辑&#xff0c;然后搜索&#xff1a;Hover:Enanbled,出现如下图&#xff0c;取消勾选即可&#xff1b;

2024常见性能测试工具!

一&#xff1a;如何选择性能工具 选择性能测试工具时&#xff0c;可以从以下几个方面进行考虑&#xff1a; 1. 需求匹配&#xff1a;首先要明确项目的具体需求&#xff0c;比如需要测试的应用类型、协议、负载规模等。确保所选工具能够满足这些需求。 2. 技术兼容性&#xf…

Vue3--数据和方法

data 组件的 data 选项是一个函数。Vue 在创建新组件实例的过程中会自动调用此函数。   data选项通常返回一个对象&#xff0c;然后 Vue 会通过响应性系统将其包裹起来&#xff0c;并以 $data 的形式存储在组件实例中。 <!DOCTYPE html> <html lang"en"&g…

已解决:android SDK安装时点击SDK Manager出现闪退

1、首先确保电脑里边安装了JDK&#xff0c;并且要把安装路径配置在环境变量里边&#xff0c;避免使用绝对路径 推荐%JAVA_HOME%\bin 2、在C:\Users\huanhuan\Desktop\android-sdk-windows\tools路径下找到android.bat文件打开&#xff0c;把set java_exe后改为jdk中java.exe的路…

孪生网络(Siamese Network)和数字孪生的区别?

1. 孪生网络 孪生网络是一种特殊的网络框架&#xff0c;基于两个人工神经网络建立的耦合构架&#xff0c;通过比较两个样本在高维度空间的表征来判断它们的相似程度。它包含两个相同结构的神经网络&#xff0c;一个用于学习&#xff0c;一个用于验证学习效果。在训练过程中&am…

【火猫TV】欧联:8强无弱队,意甲英超球队扎堆,利物浦和药厂优势很大!

2023-2024欧联杯八强正式出炉&#xff0c;马赛、本菲卡、勒沃库森、利物浦、西汉姆联、罗马、亚特兰大和AC米兰成功拿到了晋级名额&#xff0c;于是球迷们即将看到近20年竞争最激烈的欧联杯八强对决。虽然这些队伍实力有强有弱&#xff0c;但是能够拼到现在的球队没有弱旅&…

20240304 json可以包含复杂数组(数组里面套数组)

欣赏一下我的思维&#xff0c;它会以漫画&#xff0c;表格&#xff0c;文字。。。各种各样的形式呈现 对于问题1问题2 JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。JSON本质上是一种文本…

鸿蒙实战开发:【分布式软总线组件】

简介 现实中多设备间通信方式多种多样(WIFI、蓝牙等)&#xff0c;不同的通信方式使用差异大&#xff0c;导致通信问题多&#xff1b;同时还面临设备间通信链路的融合共享和冲突无法处理等挑战。分布式软总线实现近场设备间统一的分布式通信管理能力&#xff0c;提供不区分链路…
最新文章