文件打包解包的方法

文件打包

前言

在很多情况下,软件需要隐藏一些图片,防止用户对其更改,替换。例如腾讯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是\0    listSize += 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;    else      fileList[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函数:

神奇的事情发生了,图片回来了

这只是一个小知识,用的也是熟悉的文件操作,打包的文件不包含文件夹,对于文件夹的打包方式,也是通过遍历文件夹下面的所有文件和文件夹,制作一张索引表,打包到一个文件里面。

 

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

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

相关文章

动态地图开发的未来应用场景有哪些?

动态地图开发应用已经成为现代数字世界中不可或缺的一部分。这种技术的灵活性为公司和组织提供了一种简单却强大的方式&#xff0c;以在现实世界地图上显示各种信息。无论是用于自动导航系统、气象预报、实时交通状况或利用商业洞察力获取市场数据&#xff0c;动态地图开发应用…

SpringBoot整合网易邮箱

SpringBoot整合邮箱 1&#xff0c;开启POP3/SMTP/IMAP服务 注意&#xff1a;每个邮箱的密码唯一&#xff0c;不要随意分享给他人 最后就是这个样子了 2&#xff0c;整合测试 2.1&#xff0c;pom.xml <?xml version"1.0" encoding"UTF-8"?> <…

【教程】解决php微擎中的goto加密解密,一键解密工具

今天&#xff0c;我将向大家揭秘一款神奇的工具——goto解密工具&#xff0c;轻松解密这个看似棘手的问题。 无数开发者都曾因为php中的goto功能而头疼不已。goto解密工具其中之一就是解密goto代码。通过精妙的算法和强大的解析能力&#xff0c;它能够解密被goto加密的代码段&…

Tune-A-Video:用于文本到视频生成的图像扩散模型的One-shot Tuning

Tune-A-Video: One-Shot Tuning of Image Diffusion Models for Text-to-Video Generation Project&#xff1a;https://tuneavideo.github.io 原文链接&#xff1a;Tnue-A-Video:用于文本到视频生成的图像扩散模型的One-shot Tuning &#xff08;by 小样本视觉与智能前沿&…

Redis基础认识

日升时奋斗&#xff0c;日落时自省 目录 1、Redis安装及配置 2、缓存简介 2.1、缓存优点 2.2、缓存分类 2.3、常见缓存使用 2.3.1、Spring Cache 2.3.2、Redis 3、Redis数据类型和使用 3.1、字符串类型 3.2、哈希类型 3.3、列表类型 3.4、集合类型 3.5、有序集合类…

基于 unity 配置 adb

1.打开环境变量配置path的环境 2 找到自己的unity安装目录,找到对应路径 配置到 path 属性中 C:\~\Editor\2021.3.0f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\SDK\platform-tools 3 应用保存即可

42. 接雨水

题目链接&#xff1a;力扣 解题思路&#xff1a;从左往右按列进行计算&#xff0c;依次计算每一列能够接到的雨水数量。对于当前列能够接到的雨水数量是由左右两边最高的两根柱子决定的&#xff0c;类似于木桶定律&#xff08;一只水桶能装多少水取决于它最短的那块木板&#x…

TypeScript 中接口类型【Interfaces】的定义使用解读

导语&#xff1a; 什么是 类型接口&#xff1f; 在面向对象语言中&#xff0c;接口&#xff08;Interfaces&#xff09;是一个很重要的概念&#xff0c;它是对行为的抽象&#xff0c;而具体如何行动需要由类&#xff08;classes&#xff09;去实现&#xff08;implement&#x…

Redis的3大特殊数据类型(1)-BitMap

BitMap(位图/位数组)是Redis2.2.0版本中引入的一种新数据类型&#xff0c;该数据类型本质是一个仅含0和1的二进制字符串。因此可以把 Bitmap 想象成一个以位为单位的数组&#xff0c;数组的每个单元只能存储 0 和 1&#xff0c;数组的下标在 Bitmap 中叫做偏移量 offset&#x…

AI绘画Midjourney的咒语关键词汇总结

近期很多人都在研究Ai,被他强大的运算和准确性所震撼&#xff0c;和我们设计师相关的一个Ai绘画工具-Midjourney&#xff0c;绝对是占设计圈头部流量的&#xff0c;在圈内掀起一片热潮&#xff0c;今天我们就专门围绕他来展开说说&#xff0c;当然除了这个外&#xff0c;我们还…

使用 Jetpack Compose 构建 Switch

欢迎来到这篇关于如何使用 Jetpack Compose 构建 Switch&#xff08;开关&#xff09;的博客。Jetpack Compose 是 Google 的现代 UI 工具包&#xff0c;主要用于构建 Android 界面。它以声明式的方式简化了 UI 的开发。 一、什么是 Switch&#xff1f; 在 Android 中&#xf…

【PostgreSQL-16新特性之普通用户的保留连接个数(reserved_connections)】

PostgreSQL数据库为了保证在高并发&#xff0c;高连接数情况下某些用户能够正常连接到数据库里&#xff0c;设立了几个用户连接的保留个数。 本文介绍了PostgreSQL16版本前为超级用户保留的连接数&#xff08;superuser_reserved_connections&#xff09;以及PostgreSQL16版本…