Это хорошая идея - сохранить / загрузить массив структур?

Мне было интересно, было ли хорошей идеей загрузить / сохранить массив определенного типа структуры с помощью fstream. Обратите внимание, я говорю о загрузке / сохранении в двоичный файл. Должен ли я загружать / сохранять независимые переменные, такие как int, float, boolean, а не структуру? Я спрашиваю об этом потому, что слышал, что у структуры может быть какой-то заполнитель, который может компенсировать сохранение / загрузку.


person Johnathan    schedule 24.05.2011    source источник
comment
Не очень понятно, с чем вы просите нас сравнить. Не могли бы вы предоставить несколько простых фрагментов кода для каждой альтернативы?   -  person Oliver Charlesworth    schedule 24.05.2011
comment
deprecated имеет особое значение в кругах C ++ - я перефразировал ваш вопрос, чтобы избежать его использования.   -  person    schedule 24.05.2011
comment
У меня нет под рукой главы и стиха, но я уверен, что нельзя загружать / сохранять массив объектов, не относящихся к POD.   -  person Robᵩ    schedule 24.05.2011
comment
@Rob Нет, стандарт C ++ молчит по этому поводу.   -  person    schedule 24.05.2011
comment
@Rob: Здесь язык позволяет программисту стрелять ногой. Массив struct или POD - это область памяти, в которой элементы расположены непрерывно. Двоичный ввод-вывод выводится из области памяти, без ограничений (доступ к недопустимым участкам памяти перехватывается платформой или ОС).   -  person Thomas Matthews    schedule 24.05.2011


Ответы (5)


Структура может содержать заполнение, которое будет записано в файл. В этом нет ничего страшного, если файл будет считываться на той же платформе, используя код, выданный тем же компилятором, который выполнял запись. Однако это сложно гарантировать, и если вы не можете этого гарантировать, вы должны обычно записывать данные в каком-либо текстовом формате, таком как XML, json или что-то еще.

person Community    schedule 24.05.2011
comment
+1, Расширение: разные платформы и версии ОС могут по-разному представлять данные в двоичном формате. Один из таких случаев - Endianness. Также поля структуры данных должны быть записаны по отдельности с каким-то разделителем между полями. - person Thomas Matthews; 24.05.2011
comment
Под представлением данных по-разному вы имеете в виду метод Endian, а не размер, который они занимают в двоичном формате, верно? - person Johnathan; 24.05.2011
comment
@Johnathan Нет, я не это имел в виду. Структура на C или C ++ может занимать разное пространство даже на одной платформе. Но порядок байтов - определенная проблема для переносимости. Обратите внимание, что это может не иметь значения - если вы пишете приложение, скажем, для Windows, которое должно читать и писать очень быстро, то, вероятно, будет лучше записывать структуры напрямую, но ваши файлы данных не будут переносимы. - person ; 24.05.2011
comment
Таким образом, это означает, что он может не работать в Linux или Mac. - person Johnathan; 24.05.2011
comment
@Johnathan Нет, он БУДЕТ работать везде. Однако созданный файл будет полностью непереносимым. - person ; 24.05.2011

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

Взгляните на это:

person Nawaz    schedule 24.05.2011

Он не устарел (он не является частью какой-либо формальной спецификации, где он должен быть устаревшим?), Но он крайне непереносим и, вероятно, худший способ сериализации вещей. Используйте Boost.Serialization или аналогичную библиотеку.

person Cat Plus Plus    schedule 24.05.2011
comment
использование библиотеки сериализации является излишним, если двоичная совместимость не является проблемой (программа будет работать только на той же платформе / ОС, и структура гарантированно будет такой же в будущих версиях) - person CharlesB; 24.05.2011
comment
@CharlesB: И всегда будет использоваться один и тот же компилятор и одна и та же версия этого компилятора. Это просто совсем не переносимо, и отказ от библиотеки сериализации может вызвать только проблемы. - person Cat Plus Plus; 24.05.2011

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

Попробуйте записать свои данные в текст, например в текст или XML, а затем заархивировать / архивировать файлы, чтобы сделать из них один документ.

person Xolve    schedule 24.05.2011

Как сказал Нил, предпочитаю текстовое представление данных. Формат XML может быть излишним. Более простые версии - это значения, разделенные запятыми (CSV), и одно значение в каждой текстовой строке.

person Thomas Matthews    schedule 24.05.2011