c++ 逐行读取并且集成到lua中

使用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 游戏启动时会全部加载到内存中 这样虽然内存上升了 但是没有运行时的开销了

代码粗糙 仅供参考
各有利弊吧

猜你喜欢

转载自blog.csdn.net/qq_25670983/article/details/127899707