Неправильное чтение int из двоичного файла при использовании c ++ - PullRequest
0 голосов
/ 22 мая 2018

У меня сложный структурированный двоичный файл.Я создал парсер в python для чтения двоичного файла, преобразования в правильные значения и сохранения данных в csv, чтобы их можно было проанализировать.Это работает хорошо, но некоторые файлы очень большие (например, 20+ Гб) и занимают много-много часов для анализа.Я пытаюсь ускорить это путем реализации того же процесса в c ++.

Ниже приведен отрывок, который читает контрольное слово в начале каждой логической записи и указывает размер записи.Для конкретного случая контрольное слово - 128 (4 байта, Big Endian, int).В Python я делаю:

x = open(str(self.filename), "rb")
cw_d_type = np.dtype('>i4')
temp = np.frombuffer(x.read(cw_d_type.itemsize), dtype=cw_d_type)

Значение в temp [0] после этого 128. Теперь, когда я пытаюсь сделать то же самое в C ++, используя следующий код

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <sstream>
#include <stdint.h>

using namespace std

struct control_word
{
    uint32_t chunk_size;
}

int main()
{
    // define my stream
    ifstream in_f("Y:/path_to_binary_file/binary_file", ios::binary | ios::in | ios::ate);

    // find the size of the file
    int file_size = in_f.tellg();

    // goto the beginning of the file
    in_f.seekg(0, std::ios::beg);

    in_f.read(reinterpret_cast<char*>(&cw), sizeof(cw));
    cout << cw.chunk_size << endl

    ... continue reading the rest of the structures

}

Результат для cw.chunk_size = 2147483648. Я знаю, что я читаю правильное место в файле b / c, следующая структура, которую я читаю, имеет 32-битную строку, и она читается правильно, если я не был в нужном местев этом случае этот результат не будет правильным.

Если я изменю структуру моего контрольного слова с int на char[4], то получится [0][0][0][-128], что почти правильно, за исключением отрицательного знака.

Всеудвоения и числа с плавающей точкой, которые я читал, показывают то же самое.Единственное, что кажется правильно прочитанным, - это char значения.Прошло много лет с тех пор, как я последний раз программировал на с ++.Есть что-то, что я забыл сделать, чтобы правильно отобразить мой двоичный файл в мои структуры ??

Я прочитал много вопросов о чтении двоичных файлов и не могу понять, почему я получаю эти странные значения.Самый близкий ответ, который я нашел , здесь , и решение было в том, что пользователь не отображал кусок двоичного файла в правильный тип.Я знаю, что это не так для меня, b / c в моей реализации на Python, я читаю блок как int и получаю ожидаемое значение.

1 Ответ

0 голосов
/ 22 мая 2018

Согласно документации > для numpy.dtype указывается формат Big-Endian.Вы выполняете свой код, скорее всего, на Intel или совместимом процессоре, который является Little-Endian.Вам необходимо преобразовать поле uint32_t с помощью функции ntohl():

in_f.read(reinterpret_cast<char*>(&cw), sizeof(cw));
cw.chunk_size = ntohl( cw.chunk_size );
cout << cw.chunk_size << endl;

Подробная информация о Порядковый номер

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