c++存取dat数据

来源:互联网 发布:c语言 矩形 rect 编辑:程序博客网 时间:2024/06/09 23:59

      众所周知,dat是一个类似加密的二进制格式文件,很多人喜欢将游戏数据保存在dat文件中,只有知道你的存放格式,才能够将数据破解出来,因而研究了dat文件的存取方式。其实就是c++文件的操作,只不过是在取的时候需要按照自己存放的格式获取出来。

本文将实现将结构体数据保存到dat文件,并且将dat文件读取回来。

1.struct结构体的格式数据

      首先定义一个结构体,用以存放存入dat文件的数据,同时,再取的时候按照结构体的格式进行获取操作:

#pragma once#ifndef _STRUCT_H_#define _STRUCT_H_#include<vector>#include <iostream>#include <string>using namespace std;;#define MaxSize 10//设置结构体的边界对齐为1个字节,对于结构体中的char数组,如果不满4的倍数字节,会默认补齐,声明之后数据在内存中是连续存储的。#pragma pack(1) typedef struct _TEST_DAT{int type;char name[MaxSize];int age;}TESTDAT;#pragma pack()#endif 
这时的结构体内存结构是对齐的。

2.TxtToFile存取dat文件

         先说存,首先初始化一个结构体,其次将该结构体数据依次保存到指定名字的dat文件中,如下:

TxtToFile.h

#pragma once#ifndef _TXT_TO_FILE_H_#define _TXT_TO_FILE_H_#include<vector>#include <iostream>#include <fstream>#include <string>#include "Struct.h"#include <stdio.h>using namespace std;class TxtToFile{public:TxtToFile();~TxtToFile();//外调函数,保存到dat文件bool  SaveToDat(string _datPath);private:TESTDATm_dat;fstreamm_datstream;vector<TESTDAT>m_getdat;private:// 把基本的Number类型写入文件流中template<class T>bool Write(T value){//rem_datstream.write(reinterpret_cast<char *>(&value), sizeof(T));return true;}//把字符串写入文件流void  WriteString(string _str, int_count);};#endif
TxtToFile.cpp
#include "stdafx.h"#include "TxtToFile.h"#include <sstream>TxtToFile::TxtToFile(){m_dat = TESTDAT{0,"dasdasd",1};}TxtToFile::~TxtToFile(){}bool TxtToFile::SaveToDat(string _datPath){if (_datPath.size() == 0){return false;}m_datstream.open(_datPath, fstream::out | fstream::binary);//以二进制的形式打开文件if (!m_datstream.is_open()){cout << "open" << _datPath << "Failed" << endl;m_datstream.close();return false;}Write(m_dat.type);//存入数据WriteString(m_dat.name, MaxSize);Write(m_dat.age);//Write(m_dat);cout << "Successed" << endl;m_datstream.close();return true;}void TxtToFile::WriteString(string _str, int _count){if (_str.length()>=_count){cout << "write string error!" << endl;return;}m_datstream << _str;int len = _count - _str.length();while (len--){m_datstream << '\0';}}



         这个时候,已经把数据存入到dat文件中,接下来就是取数据了,如下:

首先在头文件中加两个函数:


//从dat文件读取数据bool GetFromDat(string _datPath);__int64 getFileSize(const char *filename);

cpp:
bool TxtToFile::GetFromDat(string _datPath){if (_datPath.size()==0){return false;}__int64 scount = 0;__int64 stuctsize = sizeof(TESTDAT);TESTDAT testdat;__int64 filesize = getFileSize(_datPath.c_str());if (filesize==0|| filesize<stuctsize ||(filesize%stuctsize)!=0){return false;}scount = filesize / stuctsize;FILE *inStream = NULL;const char* name = _datPath.c_str();inStream = fopen(name, "rb");if (inStream == NULL) return false;for (int i = 0; i < scount; i++){//size_t fread(void *ptr, size_t size, size_t n, FILE *stream);//参数ptr是保存读取的数据,void*的指针可用任何类型的指针来替换,如char*、int *等等来替换;//size是每块的字节数;n是读取的块数,如果成功,返回实际读取的块数(不是字节数),本函数一般用于二进制模式打开的文件中。fread(&testdat, stuctsize, 1, inStream);/*if (testdat.duration < 0){fclose(inStream);return false;}*/m_getdat.push_back(testdat);}fclose(inStream);return true;}__int64 TxtToFile::getFileSize(const char *filename){__int64 size = 0;/*FILE *fp = fopen(filename, "rb");if (!fp){return 0;}fseek(fp, 0, SEEK_END);size = ftell(fp);fseek(fp, 0, SEEK_SET);fclose(fp);*/fstream instreams;instreams.open(filename, ios::_Nocreate);if (!instreams.is_open()){return 0;}instreams.seekg(0, ios::end);size = instreams.tellg();instreams.close();return size;}
读的时候用的是C语言的,因为映射一下就是结构体了,而且存的时候没有存空格\n\t之类的分隔符,所以用getline不好取。

3.测试样例

main函数:

// DatTxt.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "TxtToFile.h"int _tmain(int argc, _TCHAR* argv[]){TxtToFile ttofile;ttofile.SaveToDat("Test.Dat");ttofile.GetFromDat("Test.Dat");return 0;}


运行视图:
成功,并且能在目录下找到dat文件,如果要看取出来的数据,那么需要加断点查看咯

Over
3 0
原创粉丝点击