Чтение и запись структур в двоичный файл представляет опасность.
Проблема, с которой вы здесь сталкиваетесь, заключается в том, что компилятор вставляет заполнение (необходимое для выравнивания) между элементами type
и identifier
вашей структуры.Очевидно, что любая программа, написавшая данные (о которых вы нам не сказали), использовала другой макет, который программа пытается прочитать данных.
Это можетпроизойдет, если две системы (одна записывает данные, а другая - читает) имеют разные требования к выравниванию и, следовательно, разные макеты для типа Entry
.
Выравнивание не единственная потенциальная проблема;Различия в endianness также могут быть серьезной проблемой.Различные системы могут иметь разные размеры для предопределенных целочисленных типов.Вы не можете предполагать, что struct Entry
будет иметь согласованную разметку, если весь код, который с ней работает, не будет работать в одной системе - и в идеале с той же версией того же компилятора.
You мог бы использовать #pragma pack
, чтобы обойти это, но я не рекомендую это.Это не портативно, и может быть небезопасно .В лучшем случае это обойдет проблему заполнения между членами;есть еще много способов, которыми макет может варьироваться от одной системы к другой.
Невозможно дать вам окончательное решение, не зная, где и как определено расположение данных файла, который вы читаете.
Если мы предположим, что формат файла для каждой записи, например:
- 2-байтовое целое число без знака в сетевом порядке (
type
) - An8-байтовое целое в сетевом порядке байтов (
identifier
) - 4-байтовое целое в сетевом порядке байтов (
offset_specifier, length
) - с добавлением нет между ними
тогда вы должны либо прочитать данные в буфер unsigned char[]
, либо в объекты типа uint16_t
, uint32_t
и uint64_t
(определенные в <cstdint>
или <stdint.h>
), а затем преобразовать его из сетевого порядка байтов в локальный порядок байтов.
Это преобразование можно заключить в функцию, которая читает файл и преобразует данные, сохраняя их в Entry
struct.
Если , вы можете предположить, что программа будет работать толькоВ ограниченном наборе систем вы можете обойти это.Например, вы можете настроить декларацию struct Entry
, чтобы она соответствовала формату файла, и прочитать и записать ее напрямую.Это будет означать, что ваш код не переносим на некоторые системы.Вам придется решить, какую цену вы готовы заплатить.