C++ 在存档中搜索文件并将其加载到内存中
基本上,我需要将归档文件中的文件加载到内存中,但由于用户能够修改归档文件的内容,因此文件偏移量很可能会发生变化 因此,我需要创建一个函数,在十六进制模式的帮助下搜索归档文件,返回文件偏移量,将文件加载到内存中,并返回文件地址 要将文件加载到内存并返回我当前使用的地址,请执行以下操作:C++ 在存档中搜索文件并将其加载到内存中,c++,memory,archive,ram,C++,Memory,Archive,Ram,基本上,我需要将归档文件中的文件加载到内存中,但由于用户能够修改归档文件的内容,因此文件偏移量很可能会发生变化 因此,我需要创建一个函数,在十六进制模式的帮助下搜索归档文件,返回文件偏移量,将文件加载到内存中,并返回文件地址 要将文件加载到内存并返回我当前使用的地址,请执行以下操作: DWORD LoadBinary(char* filePath) { FILE *file = fopen(filePath, "rb"); long fileStart = ftell(file)
DWORD LoadBinary(char* filePath)
{
FILE *file = fopen(filePath, "rb");
long fileStart = ftell(file);
fseek(file, 0, SEEK_END);
long fileSize = ftell(file);
fseek(file, fileStart, 0);
BYTE *fileBuffer = new BYTE[fileSize];
fread(fileBuffer, fileSize, 1, file);
LPVOID newmem = VirtualAlloc(NULL, fileSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(newmem, fileBuffer, fileSize);
delete[]fileBuffer;
fclose(file);
return (DWORD)newmem;
}
归档文件既不加密也不压缩,但它相当大(大约1GB),如果可能的话,我不想将整个文件加载到内存中
我知道我在归档文件中查找的文件的大小,所以我不需要函数来查找具有其他模式的文件结尾
文件模式:“\x30\x00\x00\x00\xA0\x10\x04\x00”
文件长度:4096字节
我如何实现这一点以及需要哪些功能
解决方案
对于大文件,代码可能很慢,但这对我来说很有效,因为我要查找的文件位于归档文件的开头
FILE *file = fopen("C:/data.bin", "rb");
fseek(file, 0, SEEK_END);
long fileSize = ftell(file);
rewind(file);
BYTE *buffer = new BYTE[4];
int b = 0; //bytes read
long offset = 0;
for (int i = 0; i < fileSize; i++)
{
int input = fgetc(file);
*(int *)((DWORD)buffer + b) = input;
if (b == 3)
{
b = 0;
}
else {
b = b + 1;
}
if (buffer[0] == 0xDE & buffer[1] == 0xAD & buffer[2] == 0xBE & buffer[3] == 0xEF)
{
offset = (ftell(file) - 4);
printf("Match @ 0x%08X", offset);
break;
}
}
fclose(file);
FILE*FILE=fopen(“C:/data.bin”、“rb”);
fseek(文件,0,SEEK_END);
long fileSize=ftell(文件);
倒带(文件);
字节*缓冲区=新字节[4];
int b=0//字节读取
长偏移=0;
对于(int i=0;i
原理如中所述:您需要一个有限状态机(FSM),它将文件字节一个接一个地作为输入,并根据FSM状态(模式中的索引)将当前输入与模式中的字节进行比较
以下是最简单但简单的解决方案模板:
FILE *file = fopen(path, "rb");
size_t state = 0;
for (int input_result; (input_result = fgetc(file)) != EOF;) {
char input = (char)input_result;
if (input == pattern[state]) {
++state;
} else {
state = 0;
}
if (pattern_index == pattern_size) {
// Pattern is found at (ftell(file) - pattern_size).
break;
}
}
fclose(file);
state
变量在模式中保持位置,它是FSM的状态
虽然这个解决方案满足了您的需求,但它并不是最优的,因为从文件中读取一个字节所需的时间几乎与读取更大的数据块(比如512字节或更多)所需的时间相同。您可以通过两个步骤来改进这一点:
fread()
。请注意,模式位置的计算(找到后)变得有点复杂,因为ftell()
不再与输入
位置匹配文件怎么可能相当大(大约1gb),同时文件长度为4096字节?顺便说一下,它不是1gb,它是1gb,小写的b代表位,而大写的b代表字节。Giga始终是大写字母G的符号归档文件的大小约为1GB,归档文件中的文件大小为4096字节。将编辑第一篇文章。谢谢你的回答。我确信我理解代码应该如何工作,但我不能正确地实现它。最后,我提出了一个很可能较慢的方法,但对我来说很有效,因为我要查找的文件位于归档文件的开头。所以搜索只需要3秒钟。我会接受你的回答,因为它把我引向了正确的方向。再次感谢大家。