Как работает структура порядка записи двоичных файлов?

0

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

struct MODEL
{
    FLOAT X, Y, Z;
    D3DXVECTOR3 Normal;
    FLOAT U, V;
};

struct RETURNTYPE
{
    float vsize, isize;
    MODEL* model;
    DWORD* index;
}; //actual out structure

будут ли методы на http://courses.cs.vt.edu/cs2604/fall01/binio.html означать, что они будут записаны в этом порядке и будут ли они считаны в этом порядке?

  • 2
    Если у вас есть ресурсы, которые вы используете для ответа на вопрос, скопируйте соответствующие части в свой вопрос. Вопросы по SO должны быть автономными, чтобы они продолжали быть полезными и актуальными, даже если срок действия вашей ссылки истекает.
Теги:
struct
io
binary

1 ответ

0
Лучший ответ

Не обязательно, нет. Примеры, приведенные на странице (по крайней мере, бит, которые я читаю/просматриваю) опасны, потому что вы сбрасываете необработанную память на диск, а затем читаете ее. Это не очень хорошая практика.

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

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

struct Foo {
    char* someString;
};

Затем он будет сериализован на диск как целое число, которое может быть 32-битным или 64-битным в зависимости от платформы, и это целое означает ничего, потому что адрес памяти ничего не значит на диске, особенно после процесса, который его написал закончилось.

Здесь еще одна проблема: на 68k и PowerPC (и других платформах с большими терминами) целые числа будут поменяны по байтам по сравнению с x86/x64, которые являются малоконтинентальными, что делает тот же самый код C/C++ генерирующим несовместимые файлы на разных платформах, Вот почему многие файлы не были совместимы между Mac OS и IBM PC/Windows в 1990-х годах, вам нужно было инвестировать в "программное обеспечение конвертера", которое знало, какие поля переустанавливают байтовый заказ.

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

struct Foo {
    private:
    int foo;
    public:
    void serialize(ostream& stream) {
        stream.write( htonl( foo ) ); // htonl converts integers to big-endian order
    }
    void deserialize(istream& stream) {
        stream.read( &foo, sizeof(int) );
        foo = ntohl( foo ); // convert from big-endian back to native byte-order
    }
};
  • 0
    Спасибо за это. Знаете ли вы какие-либо ресурсы, которые углубляются в сериализацию?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню