Как я могу проверить, существует ли строка в двоичном файле? - PullRequest
1 голос
/ 02 ноября 2019

У меня есть двоичный файл ( не текстовый файл), размером около 20M, и у меня есть строка, которая может существовать или не существовать в этом файле. Обычно (для текстового файла) я бы использовал getline(), чтобы прочитать файл построчно, а затем find для его обнаружения, что-то вроде:

bool found = false;
{
    std::string stringToLookFor("string to look for");
    std::ifstream ifs("myBinaryFile.bin");
    std::string line;
    while (!found && getline(ifs, line)) {
        found = (line.find(stringToLookFor, 0) != std::string::npos);
    }
    ifs.close();
}

Однако я не уверен, еслиэто разумно сделать для двоичного файла. Моя главная проблема заключается в том, что «строки» для такого файла могут быть большими. Может случиться так, что весь файл 20M не содержит новых строк, так что я могу закончить чтение довольно большой строки для поиска (вполне может быть и другие проблемы с этим подходом, отсюда и мой вопрос).

Это считается жизнеспособным подходом или я могу столкнуться с проблемами? Есть ли лучший способ поиска двоичных файлов, чем обычный текстовый построчно?

Ответы [ 2 ]

2 голосов
/ 03 ноября 2019

Я укушу наживку и попробую ответить. Вы ищете это:

//...
std::ifstream is(file_name, std::ios::binary);
if (!is)
  return -1;
auto res = std::search(std::istream_iterator<char>(is), std::istream_iterator<char>(), pattern.begin(), pattern.end());
//...

Это быстро и не загружает файл все сразу в память. Я не знаю, на чем основан алгоритм. boyer_moore_searcher нельзя использовать, поскольку istream_iterator не подходит для.

1 голос
/ 02 ноября 2019

Самый простой и быстрый способ заключается в том, как @ZDF предложил в комментариях прочитать весь файл в память и затем найти его содержимое для вашей строки:

#include <fstream>
#include <vector>
#include <algorithm>

std::ifstream ifs(filename, std::ios::binary);
ifs.seekg(0, std::ios::end);
auto size = ifs.tellg();
ifs.seekg(0);
std::vector<char> content(size, '\0');
ifs.read(content.data(), size);
auto res = std::search(content.begin(), content.end(), str.begin(), str.end());
...