Как найти строку в двоичном файле? - PullRequest
1 голос
/ 07 мая 2019

Я хочу найти определенную строку «fileSize» в двоичном файле.
Цель поиска этой строки - получить 4 байта рядом со строкой, поскольку эти 4 байта содержат размер данных, которые я хочу получить.прочитай это.

Содержимое двоичного файла выглядит следующим образом:

Та же строка в другой позиции:

Другая позиция:

Ниже приводится функция, которая записывает данные вfile:

void W_Data(char *readableFile, char *writableFile) {
    ifstream RFile(readableFile, ios::binary);
    ofstream WFile(writableFile, ios::binary | ios::app);

    RFile.seekg(0, ios::end);
    unsigned long size = (unsigned long)RFile.tellg();
    RFile.seekg(0, ios::beg);

    unsigned int bufferSize = 1024;
    char *contentsBuffer = new char[bufferSize];

    WFile.write("fileSize:", 9);
    WFile.write((char*)&size, sizeof(unsigned long));
    while (!RFile.eof()) {
        RFile.read(contentsBuffer, bufferSize);
        WFile.write(contentsBuffer, bufferSize); 
    }
    RFile.close();
    WFile.close();
    delete contentsBuffer;
    contentsBuffer = NULL;
}

Также функция, которая ищет строку:

void R_Data(char *readableFile) {
    ifstream RFile(readableFile, ios::binary);

    const unsigned int bufferSize = 9;

    char fileSize[bufferSize];
    while (RFile.read(fileSize, bufferSize)) {
        if (strcmp(fileSize, "fileSize:") == 0) {
            cout << "Exists" << endl;
        }
    }
    RFile.close();
}

Как найти определенную строку в двоичном файле?

Ответы [ 2 ]

2 голосов
/ 08 мая 2019

Я думаю об использовании find () - это простой способ поиска шаблонов.

void R_Data(const std::string filename, const std::string pattern) {
    std::ifstream(filename, std::ios::binary);
    char buffer[1024];

    while (file.read(buffer, 1024)) {
        std::string temp(buffer, 1024);
        std::size_t pos = 0, old = 0;

        while (pos != std::string::npos) {
            pos = temp.find(pattern, old);
            old = pos + pattern.length();
            if ( pos != std::string::npos )
                std::cout << "Exists" << std::endl;
        }
        file.seekg(pattern.length()-1, std::ios::cur);
    }
}
1 голос
/ 07 мая 2019

Как найти конкретную строку в двоичном файле?

Если вы не знаете расположение строки в файле, я предлагаю следующее:

  1. Найдите размер файла.
  2. Выделите память для возможности чтения всего в файле.
  3. Чтение всего из файла в выделенную память.
  4. Переберите содержимое файла и используйте std::strcmp / std::strncmp, чтобы найти строку.
  5. Освободите память, как только закончите с ней.

Есть несколько проблем с использованием

const unsigned int bufferSize = 9;

char fileSize[bufferSize];
while (RFile.read(fileSize, bufferSize)) {
    if (strcmp(fileSize, "filesize:") == 0) {
        cout << "Exists" << endl;
    }
}

Задача 1

Строка strcmp приведет к неопределенному поведению, когда fileSize фактически содержит строку "fileSize:", поскольку переменная имеет достаточно места только для 9 символов. Требуется дополнительный элемент для хранения завершающего нулевого символа. Вы можете использовать

const unsigned int bufferSize = 9;

char fileSize[bufferSize+1] = {0};
while (RFile.read(fileSize, bufferSize)) {
    if (strcmp(fileSize, "filesize:") == 0) {
        cout << "Exists" << endl;
    }
}

чтобы решить эту проблему.

Задача 2

Вы читаете содержимое файла в блоках по 9.

Первый вызов RFile.read читает первый блок из 9 символов.
Второй вызов RFile.read читает второй блок из 9 символов.
Третий вызов RFile.read читает третий блок из 9 символов. и т.д.

Следовательно, если строка "fileSize:" не находится на границе одного из таких блоков, проверка

if (strcmp(fileSize, "filesize:") == 0)

никогда не пройдет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...