【问题标题】:Searching for a string in an input stream在输入流中搜索字符串
【发布时间】:2016-02-22 17:32:17
【问题描述】:

我有一个大型二进制文件(很多 GB,因此不能将其加载到内存中),我想搜索所有出现的字符串“icpf”。

我尝试为此使用std::search,但被std::search 仅适用于前向迭代器而非输入迭代器这一事实所困扰。

标准库是否为此提供了一个快速的替代方案?还是我需要手动编码搜索(一次读取块然后std::search 读取这些块,或者ignore 全部读取直到'i',然后手动检查接下来的三个字符)?

【问题讨论】:

    标签: c++ iostream


    【解决方案1】:

    标准库是否为此提供了一个快速的替代方案?

    虽然标准 C++ 库提供了搜索文本流的方法,但它没有提供可比较的二进制流算法。

    或者我是否需要手动编码搜索(或者一次读取块然后std::search ,或者忽略所有内容直到'i' 然后手动检查接下来的三个字符)?

    编写“跳过和搜索”方法可能很棘手,因为编写跳过条目的解决方案很容易。例如,如果您在包含"icpicpf" 的文件中查找"icpf",则一次处理一个字符的简单程序在丢弃"icpi" 前缀后将无法找到"icpf" 后缀。

    如果您要自己编写代码,请考虑实现Knuth–Morris–Pratt algorithm。网上有很多可用的实现,而且它可以在流上正确运行,因为它一次只考虑一个字符,并且永远不会返回。

    【讨论】:

      【解决方案2】:

      最快的方法是将整个文件加载到内存中,然后搜索内存。

      下一个最佳选择是让硬盘保持运转。也许有一个线程将数据块读入缓冲区,另一个线程搜索缓冲区。

      沿着列表向下,将大块数据读入缓冲区,然后搜索缓冲区是一种很好的技术,尽管效率不如以前的方法。

      您可以使用std::getline 和std::string 逐行阅读。这不如块读取快,因为输入函数正在搜索换行符(并在std::string 中分配内存)。

      最坏的情况可能是逐字阅读。函数开销对于读取单个字符是不利的(通常开销与读取大块数据相同)。

      不,没有用于搜索文件的标准 C++ 库函数。某些操作系统具有用于搜索文件的实用程序;也许你可以使用其中之一。

      编辑 1:
      瓶颈是输入数据。一旦将数据放入缓冲区,就会有许多有效的搜索算法而不是蛮力(搜索第一个字母,然后搜索下一个字母等)。

      在互联网上搜索“字符串搜索算法”。

      【讨论】:

        【解决方案3】:

        我不知道有什么纯标准库的解决方案,但是内核已经实现了预取,所以应该可以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 的文件上对此进行测试。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-02
          • 2014-07-04
          • 1970-01-01
          • 1970-01-01
          • 2013-07-30
          • 2019-04-09
          相关资源
          最近更新 更多