1

我的经理告诉我创建一个测试,我需要测试某个特定单词是否存在于文件中。问题是文件可能非常大,如果测试运行很长时间,那么在回归测试期间它将失败。所以我想知道标准 C++ 中是否有任何方便的 API 可以快速告诉我这个词是否存在。我不想知道这个词的位置。该词位于文件开头附近的某个位置,但其确切位置未知。在这方面有什么帮助吗?谢谢你。

4

3 回答 3

3

如果文件没有特定的结构,除了包含单词(以任何顺序),唯一的解决方案是线性搜索,这意味着读取整个文件。如果您知道单词只能在开头附近,那么您只需搜索到该单词可以找到的最远点。

如果这还不够快,您要么必须以某种方式构造文件(排序等),要么必须加快阅读过程本身(例如 use mmap)。

于 2013-03-11T10:12:37.690 回答
0

mmap该文件,然后strnstr它可能是最好的。除非您对文件结构有所了解,否则会限制您必须搜索的区域。

extern "C" {
#include <sys/mman.h>
#include <fcntl.h>
}

#include <cstring>
#include <cerrno>
#include <iostream>

int main(int argc, char* argv[]) {

    // I don't check the arguments here, you should probably do that

    // String to search for
    char* search_string = argv[2];

    // Open the file so we can map it
    int fd = open(argv[1], O_RDONLY);
    if (fd < 0) {
        std::cout << "Open failed: " << strerror(errno) << std::endl;
        return 1;
    }

    // Find the length of the file so we know how much to map
    off_t len = lseek(fd, 0, SEEK_END);
    if (len == -1) {
        std::cout << "Seek failed: " << strerror(errno) << std::endl;
        return 1;
    }

    // map the file into memory
    char* file_contents = (char*)mmap(
        NULL, len, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
    if (file_contents == MAP_FAILED) {
        std::cout << "map failed: " << strerror(errno) << std::endl;
        return 1;
    }

    // We don't need the file open any more, we do need to unmap it later though
    close(fd);

    // Search for the string in the file here
    char* found = strnstr(file_contents, search_string, len);
    if (found == NULL)
        std::cout << "String not found" << std::endl;
    else
        std::cout << "String found @ " << found - file_contents << std::endl;

    munmap(file_contents, len);
}
于 2013-03-11T10:19:05.470 回答
0

内存映射文件访问允许您直接访问文件的某些部分,而无需将其加载到内存中。

据我所知,Qt 也提供内存映射,而 C++ 标准库也没有。

您还可以使用操作系统的本机 API。mmap对于 UNIX,CreateFileMapping对于 Windows。

于 2013-03-11T10:45:16.067 回答