我有一个很大的二进制文件(几个GB,无法将其加载到内存中),我想要在其中搜索所有出现的字符串 "icpf"。
我尝试使用 std::search
进行搜索,但是遇到了问题,因为 std::search
仅适用于前向迭代器,而不适用于输入迭代器。
标准库提供了快速的替代方法吗?还是我需要手动编写搜索代码(读取文件块然后对其进行 std::search
,或者忽略一切直到 'i' 并手动检查接下来的三个字符)?
编辑1:
瓶颈在于输入数据。一旦将数据输入缓冲区,就有许多有效的搜索算法,而不是暴力搜索(搜索第一个字母,然后搜索下一个字母等)。
在互联网上搜索“字符串搜索算法”。
我不知道任何纯标准库的解决方案,但内核已经实现了预取功能,因此可以通过mmap()
将文件映射到所需的前向迭代器:(省略错误处理)
size_t search(int fd, size_t fileSize) {
auto start = reinterpret_cast<char*>(
::mmap(nullptr, fileSize, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0));
::madvise(start, fileSize, MADV_SEQUENTIAL);
auto pattern = "icpf";
auto offset = std::search(start, start+fileSize, pattern, pattern+4);
return offset - start;
}
相信内核可以正确地进行惰性加载、预取和丢弃,这需要一点点信任。另一方面,如果你可以相信任何人做到这一点,那可能就是内核开发人员。
免责声明:我实际上没有在多GB文件上测试过这个。