сериализация — C ++: Как сохранить независимые от платформы двоичные файлы?

У меня есть 3D-том, представленный в виде вектора вектора вектора с плавающей точкой, который я хочу сохранить в двоичном файле. (Это объем плотности, восстановленный по рентгеновским снимкам, полученным с КТ-сканера.)

Теперь я мог бы сделать это следующим образом:

        //iterate through the volume
for (int x = 0; x < _xSize; ++x){
for (int y = 0; y < _ySize; ++y){
for (int z = 0; z < _zSize; ++z){
//save one float of data
stream.write((char*)&_volume[x][y][z], sizeof(float));
}
}
}

Это в основном работает. Однако я спрашиваю себя, в какой степени это не зависит от платформы. Я хотел бы создать файл, идентичный независимо от системы, в которой он был создан. Таким образом, могут быть машины под управлением Windows, Linux или Mac, они могут иметь длину слова 32 бит или 64 бит и порядок байтов с прямым или прямым порядком байтов.

Я полагаю, если бы я сделал это так, как это было сделано выше, это было бы не так. Теперь, как я мог этого достичь? Я слышал о сериализации, но я не нашел конкретного решения для этого случая.

1

Решение

Буферы протокола Google: бесплатные, кодируются в двоичный код, доступны на нескольких языках, также работают на большинстве платформ. Для ваших требований я бы серьезно рассмотреть GPB. Будьте осторожны, Google выпустил несколько версий, и они не всегда были обратно совместимы, то есть старые данные не обязательно читаются новыми версиями кода GPB. Я чувствую, что он все еще развивается и будут происходить дальнейшие изменения, что может быть неприятно, если ваш проект будет развиваться в течение многих лет.

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

2

Другие решения

Я решил проблему с помощью Qt Datastream учебный класс. Qt в любом случае является частью моего проекта, поэтому дополнительные усилия минимальны. Я могу сказать Datastream возражать точно, если я хочу сохранить свой floats использование одинарной (32-битной) или двойной (64-битной) точности, и если я хочу использовать байтовый порядок с прямым или младшим порядком байтов. Этого вполне достаточно для того, что мне нужно; Мне не нужно сериализовать объекты. Файлы, которые я сохраняю, теперь имеют одинаковый формат на всех платформах (по крайней мере, они должны), и это все, что мне нужно. После этого они будут прочитаны сторонними приложениями, которым будет предоставлена ​​эта информация (порядок байтов, точность). Так сказать это не имеет значения точно как мои поплавки спасены, но я знать как они сохраняются и что это не зависит от того, на какой платформе вы запускаете программу.

Вот как теперь выглядит код:

QDataStream out(&file);
out.setFloatingPointPrecision(QDataStream::SinglePrecision);
out.setByteOrder(QDataStream::LittleEndian);

for (int x = 0; x < _xSize; ++x){
for (int y = 0; y < _ySize; ++y){
for (int z = 0; z < _zSize; ++z){
//save one float of data
out<<_volume[x][y][z];
}
}
}
2

Я удивлен, что нет упоминания о <rpc/xdr.h> заголовок, для представления внешних данных. Я считаю, что это на всех Unix, и может даже работать на Windows: https://github.com/ralight/oncrpc-windows/blob/master/win32/include/rpc/xdr.h

XDR хранит все примитивные типы данных с прямым порядком байтов и заботится о преобразованиях для вас.

0
По вопросам рекламы [email protected]