You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++如何在文件分配表十六进制转储文件中跨多行搜索字符串

我之前处理十六进制转储文件时也遇到过一模一样的问题——逐行读取确实会把跨两行的子串拆成两半,根本搜不到。下面给你几个针对性的解决方案,从简单到复杂都有:

方法1:一次性加载整个文件到内存搜索(适合小文件)

这是最直接的方案,把整个文件内容拼成一个无换行的大字符串,直接调用find()就能覆盖所有跨行情况,代码实现也最简单:

#include <fstream>
#include <string>
#include <iostream>
#include <iterator>

int main() {
    std::ifstream dump_file("fat_dump.txt");
    if (!dump_file.is_open()) {
        std::cerr << "Failed to open the FAT dump file" << std::endl;
        return 1;
    }

    // 把整个文件读入一个字符串(自动忽略换行符的影响)
    std::string full_content((std::istreambuf_iterator<char>(dump_file)),
                             std::istreambuf_iterator<char>());

    // 替换成你要搜索的目标子串
    std::string target_substr = "d36dd2eb8fc9f20780e936e9";
    size_t found_pos = full_content.find(target_substr);

    if (found_pos != std::string::npos) {
        std::cout << "Found target at position: " << found_pos << std::endl;
    } else {
        std::cout << "Target substring not found" << std::endl;
    }

    return 0;
}

注意:如果你的FAT转储文件特别大(比如几个GB),这种方法会占用过多内存,这时候就需要用下面的流式处理方案。

方法2:滑动窗口式流式读取(适合大文件)

核心思路是每次读取一块数据,保留上一块的末尾部分(长度等于目标子串长度-1),和当前块拼接后再搜索,这样就能覆盖跨块(也就是跨原文件行)的子串:

#include <fstream>
#include <string>
#include <iostream>

int main() {
    const size_t BUFFER_SIZE = 4096; // 可根据内存情况调整
    std::string target_substr = "d36dd2eb8fc9f20780e936e9";
    size_t target_len = target_substr.size();

    if (target_len == 0) {
        std::cerr << "Target substring cannot be empty" << std::endl;
        return 1;
    }

    std::ifstream dump_file("fat_dump.txt", std::ios::binary);
    if (!dump_file.is_open()) {
        std::cerr << "Failed to open the FAT dump file" << std::endl;
        return 1;
    }

    std::string leftover; // 保存上一块的末尾,用于拼接当前块
    char temp_buffer[BUFFER_SIZE];
    bool found = false;

    while (dump_file.read(temp_buffer, BUFFER_SIZE)) {
        std::string current_block(temp_buffer, dump_file.gcount());
        // 拼接残留内容和当前块,确保跨块子串被包含
        std::string search_block = leftover + current_block;

        size_t pos = search_block.find(target_substr);
        if (pos != std::string::npos) {
            // 计算在文件中的绝对位置
            size_t total_read = dump_file.tellg() - current_block.size() - leftover.size();
            std::cout << "Found target at position: " << total_read + pos << std::endl;
            found = true;
            break;
        }

        // 更新残留内容:保留当前块最后target_len-1个字符
        if (current_block.size() >= target_len - 1) {
            leftover = current_block.substr(current_block.size() - (target_len - 1));
        } else {
            leftover = current_block;
        }
    }

    // 处理文件最后一块的残留内容
    if (!found) {
        std::string final_block(temp_buffer, dump_file.gcount());
        std::string search_block = leftover + final_block;
        size_t pos = search_block.find(target_substr);
        if (pos != std::string::npos) {
            size_t total_read = dump_file.tellg() - final_block.size() - leftover.size();
            std::cout << "Found target at position: " << total_read + pos << std::endl;
        } else {
            std::cout << "Target substring not found" << std::endl;
        }
    }

    return 0;
}

额外提示:处理十六进制转储的空格问题

如果你的目标子串是原始二进制对应的纯十六进制串,转储文件中每行的空格会干扰搜索(比如跨块的5e和7f在文件中是5e 7f),可以在读取时先去掉所有空格:

// 以方法1为例,在读取文件后添加:
full_content.erase(std::remove(full_content.begin(), full_content.end(), ' '), full_content.end());

这样就能搜索纯十六进制形式的目标串了。

内容的提问来源于stack exchange,提问作者MMMMMCK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:44:04