1

我有一个 3D 体积,表示为浮点向量的向量,我想将其保存到二进制文件中。(它是从来自 CT 扫描仪的 X 射线图像重建的密度体积。)

现在,我可以通过以下方式做到这一点:

        //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 位字长和小端或大端字节顺序。

我想如果我按照上面的方式这样做,情况就不会如此。现在我怎么能做到这一点?我听说过序列化,但我还没有为这个实例找到具体的解决方案。

4

3 回答 3

2

Google Protocol Buffers:免费,编码为二进制,提供多种语言,也适用于大多数平台。对于您的要求,我会认真考虑 GPB。不过要小心,谷歌已经发布了几个版本,它们并不总是向后兼容,即旧数据不一定能被新版本的 GPB 代码读取。我觉得它仍在发展,并且会发生进一步的变化,如果您的项目也将在多年内发展,这可能会令人讨厌。

ASN.1,它们的祖父,非常好的模式语言(可以设置值和大小约束,这是避免缓冲区溢出的好方法,如果自动生成的代码正确,可以自动验证数据流),一些免费工具,请参阅此页面(主要是虽然它们要花钱)。GPB 的模式语言是对 ASN.1 的一种拙劣模仿。

于 2015-05-01T06:29:01.453 回答
2

Datastream我使用 Qt类解决了这个问题。无论如何,Qt 是我项目的一部分,因此额外的工作量很小。Datastream如果我想floats使用单精度(32 位)或双精度(64 位)以及我想使用小端或大端字节顺序,我可以准确地告诉对象。这完全满足我的需要;我不需要序列化对象。我现在保存的文件在所有平台上都具有完全相同的格式(至少应该如此),这就是我所需要的。之后它们将被提供这些信息(字节顺序、精度)的第 3 方应用程序读取。所以说我的花车如何保存并不重要,但我知道它们是如何保存的,无论您在哪个平台上运行程序,这都是一致的。

下面是代码现在的样子:

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];
        }
    }
}
于 2015-05-03T15:45:30.970 回答
2

我很惊讶没有提到<rpc/xdr.h>外部数据表示的标题。我相信它适用于所有 unix,甚至可能适用于 Windows:https ://github.com/ralight/oncrpc-windows/blob/master/win32/include/rpc/xdr.h

XDR 以大端存储所有原始数据类型,并为您处理转换。

于 2017-05-17T07:33:10.063 回答