Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在存档中搜索文件并将其加载到内存中_C++_Memory_Archive_Ram - Fatal编程技术网

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()
    不再与
    输入
    位置匹配
  • 添加一个内部循环,以迭代刚才读取的块。和以前一样处理输入字符,这就是FSM方法证明自己有用的地方

  • 文件怎么可能相当大(大约1gb),同时文件长度为4096字节?顺便说一下,它不是1gb,它是1gb,小写的b代表位,而大写的b代表字节。Giga始终是大写字母G的符号归档文件的大小约为1GB,归档文件中的文件大小为4096字节。将编辑第一篇文章。谢谢你的回答。我确信我理解代码应该如何工作,但我不能正确地实现它。最后,我提出了一个很可能较慢的方法,但对我来说很有效,因为我要查找的文件位于归档文件的开头。所以搜索只需要3秒钟。我会接受你的回答,因为它把我引向了正确的方向。再次感谢大家。