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

文章目录

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

🍃前言

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

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

🌳实现思路

首先我们定义两个变量

一个是使用一个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.mzph.cn/news/747321.shtml

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

相关文章

未解决的问题:字符数组中元素的个数

情形1&#xff1a; #include<stdio.h> int main() {int arr_int1[10];int arr_int2[]{1,2,3,4,5};char arr_char1[10];char arr_char2[]"world";char arr_char3[]{h,e,l,l,o};int i;i0;while(arr_char2[i]!\0){i;}printf("%d\n",i);i0;while(arr_ch…

lwip优化任务优先级

在lwIP中&#xff0c;ethernetif_input线程负责接收和处理从以太网接口接收到的数据包&#xff0c;而tcpip主线程则负责处理lwIP协议栈中的各种事件和数据包。一般情况下&#xff0c;ethernetif_input线程的优先级应该设置为低于tcpip主线程的优先级。 这是因为在实时操作系统…

HarmonyOS ArkUI入门—HarmonyOS ArkUI来开发一个健康饮食应用

本文演示如果在DevEco Studio 3里面&#xff0c;用HarmonyOS的ArkUI来开发一个健康饮食应用。体验HarmonyOS 3最新API 9&#xff01; 获取HarmonyOS应用 HarmonyOS的ArkUI来开发一个健康饮食的ArkUI程序“ArkUIHealthyDiet”&#xff0c;基础代码已经有了[1]&#xff0c;个人…

20 OpenCV像素重映

文章目录 像素重映remap 重映算子代码示例 像素重映 简单点说就是把输入图像中各个像素按照一定的规则映射到另外一张图像的对应位置上去&#xff0c;形成一张新的图像。 g(x,y)是重映射之后的图像&#xff0c;h(x,y)是功能函数&#xff0c;f是源图像 remap 重映算子 Remap…

Java项目:52 springboot基于SpringBoot的旅游网站的设计与实现013

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 旅游网站主要功能如下&#xff1a; 1.用户管理&#xff1a;注册、登录、退出、修改密码&#xff1b; 2.分类显示&#xff1a;显示旅游路线的分类&am…

MD5算法:密码学中的传奇

title: MD5算法&#xff1a;密码学中的传奇 date: 2024/3/15 20:08:07 updated: 2024/3/15 20:08:07 tags: MD5起源算法原理安全分析优缺点比较技术改进示例代码应用趋势 MD5算法起源&#xff1a; MD5&#xff08;Message Digest Algorithm 5&#xff09;算法是由MIT的计算机…

OpenHarmony教程指南—ArkTS时钟

简单时钟 介绍 本示例通过使用ohos.display 接口以及Canvas组件来实现一个简单的时钟应用。 效果预览 使用说明 1.界面通过setInterval实现周期性实时刷新时间&#xff0c;使用Canvas绘制时钟&#xff0c;指针旋转角度通过计算得出。 例如&#xff1a;"2 * Math.PI /…

Python QT 之PySide6简单入门

目录 1.开发环境配置 1.1 下载PySide6 2.2 配置pycharm相关快捷方式 PySide6_Designer - QT Designer 设计UI PySide6_UIC - 将QT Designer生成的UI文件转换为python文件 PySide6_RCC - 将RCC文件转换为python文件 2.第一个开发实例 2.1 QT desiger设计界面 2.2 将ui文…

一篇普通的生活周记

学习进度汇报&#xff1a; 这周主要是参考着视频敲完了一个vue2后台项目&#xff0c;主要是vue2element-ui,因为之前写项目的时候用过lay-ui&#xff0c;虽然是结合着node.js写的&#xff0c;但是大差不差&#xff0c;所以上手也很快。同时&#xff0c;学长发给我们了ruoyi项目…

关于如何重燃学习的激情

3月1日是我回学校的第一天。经历了长达8个月在家的昏暗时刻&#xff0c;我这10天的感觉和在家的感觉发生了翻天覆地的变化&#xff0c;最明显的莫过于学习状态的改变。 倒不是说在家学的不好&#xff0c;而是说在学校&#xff0c;我对学习的整体感觉&#xff0c;以及专注程度&…

【Leetcode每日一题】 递归 - 反转链表(难度⭐)(35)

1. 题目解析 题目链接&#xff1a;206. 反转链表 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 一、递归函数的核心任务 递归函数的主要职责是接受一个链表的头指针&#xff0c;并返回该链表逆序后的新头结点。递归…

【LeetCode热题100】160. 相交链表(链表)

一.题目要求 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数…

获取淘宝商品详情API数据指南(item_get-获得淘宝商品详情)

获取淘宝商品详情API数据是一个复杂的过程&#xff0c;涉及到多个步骤和可能的权限问题。以下是一个基本的指南&#xff0c;帮助你了解如何使用item_get接口获取淘宝商品详情。 1. 注册淘宝开放平台账号 首先&#xff0c;你需要在淘宝开放平台注册一个账号。这是获取API权限和…

稀碎从零算法笔记Day18-LeetCode:移除链表元素

前言&#xff1a;接近20day的时间&#xff0c;终于来到了链表。 题型&#xff1a;指针、链表 链接&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你…

使用 Docker Compose 快速搭建监控网站 uptime-kuma

有时候需要监控自己搭建的一些网站、服务是否正常运行&#xff0c; 这时候可以考虑使用一个监控网站&#xff0c; 定时的进行检测&#xff0c; 记录网站、服务的运行状态&#xff0c; 在这推荐使用 uptime-kuma。 博主博客 https://blog.uso6.comhttps://blog.csdn.net/dxk539…

精读《精通 console.log》

1 引言 本周精读的文章是 Mastering JS console.log like a Pro&#xff0c;一起来更全面的认识 console 吧&#xff01; 2 概述 & 精读 console 的功能主要在于控制台打印&#xff0c;它可以打印任何字符、对象、甚至 DOM 元素和系统信息&#xff0c;下面一一介绍。 c…

【机器学习】机器学习创建算法第2篇:K-近邻算法【附代码文档】

机器学习&#xff08;算法篇&#xff09;完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;机器学习算法课程定位、目标&#xff0c;K-近邻算法&#xff0c;1.1 K-近邻算法简介&#xff0c;1.2 k近邻算法api初步使用定位,目标,学习目标,1 什么是K-近邻算法,…

Docker-数据卷、网络、dockerfile、挂载

目录 一、数据卷 二、MySQL数据 三、具名和匿名挂载 1、匿名挂载 2、具名挂载 3、指定挂载 四、Dockerfile 1、数据卷容器 2、dockerfile构建步骤 五、数据卷容器 1、实现多个容器之间数据共享 2、多个mysql之间共享数据库 六、Docker网络 1、Docker0 1、查看容器…

一些不重要的概念

QPS&#xff1a;Queries Per Second是衡量信息检索系统&#xff08;例如搜索引擎或数据库&#xff09;在一秒钟内接收到的搜索流量的一种常见度量。该术语在任何请求-响应系统中都得到更广泛的使用&#xff0c;更正确地称为每秒请求数&#xff08;RPS&#xff1a;Request Per S…

瑞吉外卖:异常处理与文件操作

文章目录 全局异常处理器文件上传文件下载 全局异常处理器 在程序中使用异常处理器进行全局异常捕获&#xff0c;此处主要处理SQLIntegrityConstraintViolationException异常&#xff0c;在reggie->common里面新建一个全局的异常捕获类 GlobalExceptionHandler.java&#x…