使用c++读取游戏配置表 并集成到lua中
集成到lua中就不写了 那个很简单 根据数据类型使用tolua.c的接口push上去就行了
然后把写好的c++代码编译到luadll中即可
测试环境
test.txt 4679行 1651kb 一般游戏中这种配置算比较的庞大的了 就用极端一点的进行测试
变量定义
#include <iostream>
#include <fstream>
#include <istream>
#include <vector>
#include <string>
#include <windows.h>
using namespace std
char path[] = "test.txt";
FILE* pFile;
long size;
char* buffer;
size_t result;
第一种方法
cout << "getline, time: " << GetTickCount64() << endl;
string buf;
while (getline(ifs, buf))
{
}
cout << "getline end, time: " << GetTickCount64() << endl;
第一种方法耗时 532ms
第二种方法
#define SPACE "\t"
#define LINE "\n"
class LineData
{
private:
vector<char*> values;
void Init(char* buffer)
{
char* data = getData(start, end, buffer);
if (data)
{
char* str = strtok(data, SPACE);
while (str != NULL)
{
values.push_back(str);
str = strtok(NULL, SPACE);
}
}
}
public:
int start;
int end;
vector<char*> GetValues(char* buffer)
{
if (values.empty())
Init(buffer);
return values;
}
};
char* getData(int start, int end, char* buffer);
char* getData(int start, int end, char* buffer)
{
char* data = (char*)malloc(sizeof(char) * (end - start));
if (data)
{
for (int i = start; i < end; i++)
{
data[i - start] = buffer[i];
}
}
return data;
}
cout << "read buffer, time: " << GetTickCount64() << endl;
pFile = fopen(path, "rb");
if (pFile == NULL)
{
fputs("file Error", stderr);
exit(1);
}
fseek(pFile, 0, SEEK_END);
size = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
//为整个文件分配内存缓冲区
size_t charSize = sizeof(char);
size *= charSize;
buffer = (char*)malloc(size + 1);
if (buffer == NULL)
{
fputs("memory error", stderr);
exit(2);
}
result = fread(buffer, 1, size, pFile);
buffer[size] = '\0';
if (result != size)
{
fputs("reading error", stderr);
exit(3);
}
vector<LineData> lineDatas;
LineData lineData;
for (int i = 0; i < size; i++)
{
if (buffer[i] == '\n' || buffer[i] == '\0')
{
lineData.start = lineData.end;
lineData.end = i;
lineDatas.push_back(lineData);
}
}
cout << "read buffer end, time: " << GetTickCount64() << endl;
cout << "get line data, time: " << GetTickCount64() << endl;
//获取某一行的数据
LineData names = lineDatas.at(3);
//将这一行的数据结构化
vector<char*> values = names.GetValues(buffer);
cout << "get line data end, time: " << GetTickCount64() << endl;
第二种方法耗时 16ms
第二种方法可以使用在游戏中, 读取配置表 把该方法集成到lua中重新编译luadll
比如这样 local tLineData = TabFile:GetTable(path, 10) 返回第十行的table
或者这样 local nID, sName = TabFile:GetTable(path, 10, “ID”, “Name”) 根据字段名返回对应配置 这种方法也不会去newluatable 性能更好
还有一种读表方式是直接把配置表导成luatable 游戏启动时会全部加载到内存中 这样虽然内存上升了 但是没有运行时的开销了
代码粗糙 仅供参考
各有利弊吧