文件打包解包的方法
在很多情况下,软件需要隐藏一些图片,防止用户对其更改,替换。例如腾讯QQ里面的资源图片,哪怕你用Everything去搜索也搜索不到,那是因为腾讯QQ对这些资源图片进行了打包,当软件运行的时候解包获取资源图片。
举个栗子:

这是我用RDB打包解包工具对QQ某一目录下的.rdb文件进行解包得到的表情包资源,还有头像资源等等。。
这种打包不是压缩包那种经过算法压缩,而是将一堆资源写入到一个文件里面,解包的时候按照打包的方式读取,达到防止用户出于恶趣味更改图片资源。
就好比你在清理内存的时候删除了一些较大的文件,恰巧这个文件就是某游戏的地图资源,导致某游戏地图变成黑色区域。所以就有建议不要乱删电脑里面的任何不确定的文件。
这期介绍下C++利用文件操作进行文件的打包解包..
要想将文件打包生成文件,我们需要一张索引表,索引表里面包括关于文件的信息,例如文件名,文件大小..
索引表之后就是文件内容,假设我有四张图片,需要将四张图片打包生成一个.pack包,并且pack包能够被解开获取里面的内容
首先看一下索引表有什么内容

首先是红色区域,占8个字节,存储索引表的信息,索引表的左边是索引表的大小,右边是文件数量
其次是索引表中包含的文件信息,从左到右依次是文件名大小、文件偏移量,文件大小,文件名
文件偏移量:就是资源文件在打包文件中的位置
然后开始关于C++文件操作的打包解包:
#include<iostream>using namespace std;#include <fstream>//索引表大小:4 文件数量:4 文件1大小 文件1偏移 文件1名大小 文件1名 文件2.。。struct FileInfo{int fileNameSize; //文件名字大小int fileOffset; //文件的偏移量int fileSize; //文件的大小char fileName[20]; //文件名};void packFile(){FileInfo fileList[4] = {{ 0,0,0,"1.jpg" },{ 0,0,0,"2.jpg" },{ 0,0,0,"3.jpg" },{ 0,0,0,"4.jpg" }};fstream file[4];int listSize = 0; //索引表大小int fileNum = 4; //文件数量for (int i = 0; i < 4; i++){fileList[i].fileNameSize = strlen(fileList[i].fileName) + 1; //1是\0listSize += fileList[i].fileNameSize + 12; //求索引表的大小file[i].open(fileList[i].fileName, ios_base::in | ios_base::binary); //打开文件file[i].seekp(0, ios_base::end); //读指针移动到末尾fileList[i].fileSize = file[i].tellp(); //获取文件大小file[i].seekp(0, ios_base::beg); //读指针移动到开头}//写文件索引信息fstream outfile("new.pack", ios_base::out | ios_base::binary);outfile.write((char*)&listSize, 4);outfile.write((char*)&fileNum, 4);//写索引表for (int i = 0; i < 4; i++){if (i == 0)fileList[i].fileOffset = 8 + listSize;elsefileList[i].fileOffset = fileList[i - 1].fileOffset + fileList[i - 1].fileSize;outfile.write((char*)&fileList[i].fileNameSize, 4);outfile.write((char*)&fileList[i].fileOffset, 4);outfile.write((char*)&fileList[i].fileSize, 4);outfile.write((char*)&fileList[i].fileName, fileList[i].fileNameSize);}//写文件char ch;for (int i = 0; i < 4; i++){while (ch = file[i].get(),!file[i].eof()){outfile.put(ch);}file[i].close();}outfile.close();}void unPackFile(){fstream inFile;inFile.open("new.pack", ios_base::in | ios_base::binary);int listSize; //索引表大小int fileNum; //文件数量//读文件索引信息inFile.read((char*)&listSize, 4);inFile.read((char*)&fileNum, 4);FileInfo* fileList = new FileInfo[fileNum];fstream *file = new fstream[fileNum];//读索引表for (int i = 0; i < fileNum; i++){inFile.read((char*)&fileList[i].fileNameSize, 4);inFile.read((char*)&fileList[i].fileOffset, 4);inFile.read((char*)&fileList[i].fileSize, 4);inFile.read((char*)&fileList[i].fileName, fileList[i].fileNameSize);file[i].open(fileList[i].fileName, ios_base::out|ios_base::binary);}for (int i = 0; i < fileNum; i++){for (int j = 0; j < fileList[i].fileSize; j++){file[i].put(inFile.get());}file[i].close();}inFile.close();delete[] fileList;delete[] file;}int main(){packFile();//unPackFile();return 0;}
工作目录下准备4张用于打包的图片:

运行程序,得到new.pack文件:

删除掉4张jpg图片,只留下new.pack文件:

调用upPackFile函数:

神奇的事情发生了,图片回来了
这只是一个小知识,用的也是熟悉的文件操作,打包的文件不包含文件夹,对于文件夹的打包方式,也是通过遍历文件夹下面的所有文件和文件夹,制作一张索引表,打包到一个文件里面。
相关文章:
文件打包解包的方法
在很多情况下,软件需要隐藏一些图片,防止用户对其更改,替换。例如腾讯QQ里面的资源图片,哪怕你用Everything去搜索也搜索不到,那是因为腾讯QQ对这些资源图片进行了打包,当软件运行的时候解包获取资源图片。…...
npm 清缓存(重新安装node-modules)
安装node依赖包的会出现失败的情况,如下图所示: 此时 提示有些依赖树有冲突,根据提示 “ this command with --force or --legacy-peer-deps” 执行命令即可。 具体步骤如下: 1、先删除本地node-modules包 2、删掉page-loacl…...
sqlserver查询表中所有字段信息
精简 SELECT 字段名 a.name,主键 case when exists(SELECT 1 FROM sysobjects where xtypePK and parent_obja.id and name in (SELECT name FROM sysindexes WHERE indid in( SELECT indid FROM sysindexkeys WHERE id a.id AND colida.colid))) then √ else …...
二叉树的概念、存储及遍历
一、二叉树的概念 1、二叉树的定义 二叉树( binary tree)是 n 个结点的有限集合,该集合或为空集(空二叉树),或由一个根结点与两棵互不相交的,称为根结点的左子树、右子树的二叉树构成。 二叉树的…...
【面试题】智力题
文章目录 腾讯1000瓶毒药里面只有1瓶是有毒的,问需要多少只老鼠才能在24小时后试出那瓶有毒。有两根不规则的绳子,两根绳子从头烧到尾均需要一个小时,现在有一个45分钟的比赛,裁判员忘记带计时器,你能否通过烧绳子的方…...
【SpringBoot集成Redis + Session持久化存储到Redis】
目录 SpringBoot集成Redis 1.添加 redis 依赖 2.配置 redis 3.手动操作 redis Session持久化存储到Redis 1.添加依赖 2.修改redis配置 3.存储和读取String类型的代码 4.存储和读取对象类型的代码 5.序列化细节 SpringBoot集成Redis 1.添加 redis 依赖 …...
day49:QT day2,信号与槽、对话框
一、完善登录框 点击登录按钮后,判断账号(admin)和密码(123456)是否一致,如果匹配失败,则弹出错误对话框,文本内容“账号密码不匹配,是否重新登录”,给定两个…...
Meta分析核心技术
Meta分析是针对某一科研问题,根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法,对来源不同的研究成果进行收集、合并及定量统计分析的方法,最早出现于“循证医学”,现已广泛应用于农林生态,资源环境等方面。…...
Gof23设计模式之责任链模式
1.概述 责任链模式又名职责链模式,为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止…...
数字孪生和元宇宙:打造未来的数字边界
数字孪生和元宇宙是近两年来被热议的两个概念,但由于技术的交叉两者也极易被混淆。本文希望带大家深入探讨一下这两者之间的关系,以及它们如何一起构建了数字时代的新格局。 1. 数字孪生的本质 数字孪生是一种虚拟模型,它通过数字手段对现实…...
【新版】系统架构设计师 - 软件架构设计<新版>
个人总结,仅供参考,欢迎加好友一起讨论 文章目录 架构 - 软件架构设计<新版>考点摘要概念架构的 4 1 视图架构描述语言ADL基于架构的软件开发方法ABSDABSD的开发模型ABSDMABSD(ABSDM模型)的开发过程 软件架…...
Linux面试题
当准备 Linux 面试时,以下是一些可能会遇到的常见 Linux 面试题: 1. 什么是Linux?解释一下Linux操作系统的特点。 2. 什么是Linux内核?Linux内核的作用是什么? 3. 如何在Linux系统上查看当前的IP地址和子网掩码&#…...
NODEJS版本管理工具
一、使用NVM 下载 Linux下载 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh widows下载地址 https://github.com/coreybutler/nvm-windows/releases 安装Node.js版本: nvm install 14.16.0 切换Node.js版本: nvm use …...
【个人笔记本】本地化部署 类chatgpt模型 详细流程
不推荐小白,环境配置比较复杂 全部流程 下载原始模型:Chinese-LLaMA-Alpaca-2linux部署llamacpp环境使用llamacpp将Chinese-LLaMA-Alpaca-2模型转换为gguf模型windows部署Text generation web UI 环境使用Text generation web UI 加载模型并进行对话 准…...
RFID与人工智能怎么融合,RFID与人工智能融合的应用
随着物联网技术的不断发展,现实世界与数字世界的桥梁已经被打通。物联网通过各种传感器,将现实世界中的光、电、热等信号转化为有价值的数据。这些数据可以通过RFID技术进行自动收集和传输,然后经由人工智能算法进行分析、建模和预测…...
性能测试 —— Jmeter 常用三种定时器
1、同步定时器 位置:HTTP请求->定时器->Synchronizing Timer 当需要进行大量用户的并发测试时,为了让用户能真正的同时执行,添加同步定时器,用户阻塞线程,知道线程数达到预先配置的数值,才开始执行…...
每个高级前端工程师都应该知道的前端布局
首发于公众号 大迁世界,欢迎关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 😜 分享个人创业过程中的趣事 快来免费体验ChatGpt plus版本的,我们出的钱 体验地址:https://chat.waixingyun.cn 可以加入网站底部技术群,一起找bug,另外新版作图神器已上线…...
100道基于Android毕业设计的选题题目,持续更新
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,Csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 大家好,我是程序员徐师兄、今天给大家谈谈基于android的app开发毕设题目,以及基于an…...
idea显示git分支信息(GitToolBox插件)
效果图 说明 本身idea在右下角会有git分支信息,但是显示的当前打开文件的分支信息,并且不够显眼 解决 1、安装插件(GitToolBox插件) 2、修改idea.properties project.tree.structure.show.urlfalse ide.tree.horizontal.default.autoscrollingfalse将…...
Hadoop知识点之Hadoop发展历程
一、Hadoop名字的起源 Hadoop这个名字不是一个缩写,它是一个虚构的名字。 该项目的创建者,Doug Cutting如此解释Hadoop: 这个名字是我孩子给一头吃饱了的棕黄色大象命名的。我的命名标准就是简短,容易发音和拼写,没有…...
Purpur性能调优实战指南:7大核心优化方案深度解析
Purpur性能调优实战指南:7大核心优化方案深度解析 【免费下载链接】Purpur Purpur is a drop-in replacement for Paper servers designed for configurability, and new fun and exciting gameplay features. 项目地址: https://gitcode.com/gh_mirrors/pu/Purpu…...
技术视角:分布式投票系统的异步解耦架构与多语言协同实践
技术视角:分布式投票系统的异步解耦架构与多语言协同实践 【免费下载链接】example-voting-app Example Docker Compose app 项目地址: https://gitcode.com/gh_mirrors/exa/example-voting-app 在当今企业级应用架构设计中,如何平衡高并发处理、…...
保姆级教程:用CH34xSerCfg修改USB转串口芯片的VID/PID,解决驱动冲突和串口号固定问题
嵌入式开发实战:用CH34xSerCfg定制USB转串口设备标识与驱动管理 当你的工作台上同时连接着五个相同型号的USB转TTL模块,Windows设备管理器里COM端口像走马灯一样随机变换编号时;当团队协作开发中,每个成员需要固定识别自己的调试设…...
AI智能体编排平台:从任务自动化到生态协作的架构与实践
1. 项目概述:一个面向AI编排与技能提升的生态协作平台最近在和一些做AI应用开发的朋友聊天,大家普遍有个痛点:现在AI工具和模型太多了,从大语言模型到图像生成,再到各种自动化脚本,每个都很强大,…...
Supabase AI Agent技能库:安全集成数据库操作与边缘函数调用
1. 项目概述:当Supabase遇上AI Agent,一个技能库的诞生最近在捣鼓AI Agent应用开发,发现一个挺有意思的现象:大家都能用LangChain、LlamaIndex这些框架快速搭出个Agent的架子,但真想让这个Agent去干点具体、有用的活儿…...
OpenClaw 小龙虾智能体联动 DeepSeek 大模型部署实操攻略
前置准备 获取小龙虾open claw一键安装包(www.totom.top)并安装电脑端已成功安装并正常启动OpenClaw,右上角 Gateway 状态显示在线设备网络通畅,可正常访问 DeepSeek 开放平台拥有可接收验证码的手机号 / 微信,用于平…...
设计师速存!Midjourney未公开的风格隐藏开关:--style raw、--s 750、--no texture三者协同作用的神经渲染原理(GPU显存占用下降41%实测)
更多请点击: https://intelliparadigm.com 第一章:设计师速存!Midjourney未公开的风格隐藏开关:--style raw、--s 750、--no texture三者协同作用的神经渲染原理(GPU显存占用下降41%实测) Midjourney v6.1…...
MQ-3与MiCS-5524气体传感器对比:从原理到实战的选型指南
1. 项目概述与核心价值在嵌入式开发、环境监测乃至一些创意DIY项目中,气体检测是一个常见且关键的需求。无论是为了安全预警(如天然气泄漏),还是进行环境质量评估(如VOC监测),选择一款合适的传感…...
嵌入式事件驱动框架Curtroller:模块化设计提升开发效率
1. 项目概述与核心价值最近在嵌入式开发社区里,一个名为“Curtroller”的项目引起了我的注意。这个项目由开发者KenWuqianghao在GitHub上开源,名字本身就是一个巧妙的组合——“Curt”(可能是“Current”电流的缩写或“Control”控制的变体&a…...
汽车该多久换一代
汽车该多久换一代 买车的人其实不怕四年换代,怕的是刚提车半年就被新款打成旧款。李想这句话能引起讨论,原因也在这里:车企说的是研发验证周期,车主感受到的是价格、配置和二手残值。 汽车确实没法完全照着手机节奏跑。手机坏了可…...
