自用二进制文件读取类

在解析一些数据库或文件中,有些内容会用一些有规定的规则进行存储,如mmkv,这种时候如果需要提取内容只能对其进行拆分,而一般都是用二进制流的读取方式读取规律解析
这是自己写的一个二进制流数据读取类
二进制流数据读取类

这边是一个qq消息的内容文件
在这里插入图片描述
可以看到消息内容是根据一定方式存储的,粗略来看前8个字节为标志,表示为是一个MSG消息,后8位不明
然后消息内容的存储都是以TD(54 44 01 01)来进行标记
那么可以进行如下解析
简单作个图
在这里插入图片描述

即可以这样

#include"ByteRead.h"
#include<iostream>
#include<fstream>
#include <memory>
#include<vector>
bool CheckLen(int at, int len)
{
	if (at > len || at < 0)
		return false;
	return true;
}
int main()
{
	std::ifstream file;
	file.open("MsgContent1", std::ios::in||std::ios::binary);
	if (file.fail())
	{
		return 0;
	}
	file.seekg(0, file.end);
	int length = file.tellg();
	std::cout << "文件大小为:" << length << std::endl;
	file.seekg(0, file.beg);
	auto buffer = std::make_shared<char>(length);
	file.read(buffer.get(), length);
	file.close();

	ByteReader byte_read((unsigned char*)buffer.get(), length);
	unsigned int head = byte_read.GetUInt32(); //获取4位标识
	if (Head != 0x0047534d) //Msg
	{
		return 0;
	}
	byte_read.Skip(8);
	unsigned char  pPath[4] = { 0x54,0x44,0x01,0x01 };
	int at = byte_read.FindChar(pPath, 4, byte_read.offset_); //找到TD这个标志
	if (at < 0)
	{
		return 0;
	}
	int next = byte_read.FindChar(pPath, 4, at + 4);//再找下一个TD
	int64_t space;
	if (next < 0)   //因为规律并不明确,我们需要防止在读取时过界导致程序出错,所以计算出每个TD之间的长度,如果在解析一段时超出则退出或进行标记,来看是什么情况
		space = byte_read.len_ - at;
	else
		space = next - at;
	byte_read.Skip(at - byte_read.offset_); //将byte_read的下标移动到读取的地方,即第一个TD的地方
	byte_read.Skip(6);//再往后6位
	int ntype = byte_read.GetByte(); //读取1位为表示这个内容的类型,GetByte()自动移了1位

	int nLen = byte_read.GetUInt16(); //读取两位为这个内容key的长度
	if (!CheckLen(nLen, space - (byte_read.offset_ - at))) //保证不超过两个TD的距离
		return 0;
	byte_read.Skip(2); //移动2位
	std::string strUnknow = byte_read.GetString(byte_read.offset_, nLen);//根据长度获取key 
	byte_read.Skip(nLen);
	nLen = byte_read.GetUInt32();
	if (!CheckLen(nLen, space - (byte_read.offset_ - at)))
		return 0;
	byte_read.Skip(4);
	std::string strUnknow1 = byte_read.GetString(byte_read.offset_, nLen);//根据长度获取value,即数据存储方式为KEY-VALUE,key和value进行了加密,需要解密才能知道正确内容
}

因为解析复杂,这里只给出了取一段的方式,可以根据上面给出的例子发现第一个TD的value其实是一个嵌套了TD的(长度为99 00 00 00),需要再次处理。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值