Как записать двоичные данные в файл, чтобы его можно было быстро прочитать обратно? - PullRequest
2 голосов
/ 19 июня 2009

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

Он должен иметь возможность читать данные довольно быстро, что должно включать в себя разбивку большого блока данных на std::vector (поскольку их хранение всегда осуществляется непрерывно).

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

Как это сделать? Я использую gcc на Buntu Linux на Q6600 (x86).

Просто в качестве примера:

struct Vertex
{
  float point [3];
  float normal [3];
  float texcoord [2];
}

Позже данные сохраняются в std::vector<Vertex>. Я думал об использовании __attribute__ и его упаковке / выравнивании, чтобы он был более переносимым на разных платформах.

редактирование: Я уже сделал спецификацию и собираюсь ее использовать. Самые большие биты данных - это вершины и индексы, поэтому они будут читаться как большие блоки, например (одна часть большей спецификации): VertexGroup - это группа вершин, которые имеют общую характеристику. Они могут содержать только один материал за раз, поэтому их должно быть много в сетке.

<uint> thisid # Of this VertexGroup
<string> name
<uint> materialId # A material
<uint> vertexCount
for (vetexCount):
    <3xfloat> point
    <3xfloat> normal
    <2xfloat> texcoord
<uint> triangleCount
for (triangleCount):
    <3xuint> indices

Ответы [ 2 ]

2 голосов
/ 19 июня 2009

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

Однако и VC ++, и GCC (большие два) поддерживают директиву #pragma pack, которая позволит вам определить выравнивание и упаковку для вашей структуры. См http://msdn.microsoft.com/en-us/library/2e70t5y1.aspx или http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html.

Имея это в виду, вы можете использовать #pragma pack для определения того, как выровняется ваша структура, затем fread() или аналогичный, чтобы просто перебирать байты из файла в память. Возможно, вы захотите добавить к списку длину списка, чтобы вы могли выделить память для всего списка сразу, а затем загрузить весь файл с помощью одного вызова ввода-вывода.

1 голос
/ 19 июня 2009

Если это просто POD (обычные старые данные), без указателей, то вы можете просто fwrite и fread. Это предполагает, конечно, что вы будете абсолютно точно читать тот же формат, что и раньше, на той же архитектуре.

Рассмотрим усиление сериализации .

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