Что такое переносимый способ записи структуры в файл в C? - PullRequest
13 голосов
/ 25 ноября 2010

Мне нужно сериализовать C struct в файл переносимым способом, чтобы я мог прочитать файл на других машинах и получить гарантию того, что получу то же, что вставил.

Формат файла не имеет значения, если он достаточно компактен (выписывание представления структуры в памяти было бы идеальным, если бы не проблемы переносимости.)

Есть ли простой способ добиться этого?

Ответы [ 3 ]

17 голосов
/ 25 ноября 2010

По сути, вы разрабатываете двоичный сетевой протокол, поэтому вы можете использовать существующую библиотеку (например, буферы протокола Google). Если вы все еще хотите создать свой собственный, вы можете добиться разумной переносимости написания необработанных структур, выполнив следующее:

  1. Упакуйте свои структуры (GCC __attribute__((packed)), MSVC #pragma pack). Это зависит от компилятора.
  2. Убедитесь, что ваш целочисленный порядковый номер указан правильно (htons, htonl). Это зависит от архитектуры.
  3. Не используйте указатели для строк (используйте символьные буферы).
  4. Используйте точные целые размеры C99 (uint32_t и т. Д.).
  5. Убедитесь, что код компилируется только там, где CHAR_BIT равно 8, что является наиболее распространенным, или иначе обрабатывает преобразование символьных строк в поток 8-битных октетов. В некоторых средах CHAR_BIT! = 8, но, как правило, это оборудование специального назначения.

При этом вы можете быть уверены, что получите другой результат на том же конце, если используете то же определение структуры. Однако я не уверен в представлении чисел с плавающей запятой, но я обычно избегаю посылать их.

Еще одна вещь, не связанная с переносимостью, к которой вы, возможно, захотите обратиться, это обратная совместимость путем введения длины в качестве первого поля и / или использования тега версии.

2 голосов
/ 25 ноября 2010

Вы можете попробовать использовать библиотеку, такую ​​как буферы протокола;кататься самостоятельно, наверное, не стоит усилий.

0 голосов
/ 25 ноября 2010

Написать одну функцию для вывода.Используйте sprintf для печати ascii-представления каждого поля в файл, по одному полю на строку.

Напишите одну функцию для ввода.Используйте fgets для загрузки каждой строки из файла.Используйте scanf для преобразования в двоичный файл, непосредственно в поле в вашей структуре.

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

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