是否可以在不同系统中使用fwrite转储文件?

时间:2010-02-03 16:24:07

标签: c++ binary struct fread fwrite

我可以假设使用fwrite生成的文件和使用fread读取的文件可以跨不同系统移植。 32位/ 64位Windows,osx,linux。

//dumping
FILE *of =fopen("dumped.bin","w");
double *var=new double[10];
fwrite(var, sizeof(double), 10,FILE);
//reading
file *fo=fopen()
double *var=new double[10];
fread(var,sizeof(double),10,of);

结构

struct mat_t{
    size_t x;
    size_t y;
    double **matrix;
}

这些便携式吗?

5 个答案:

答案 0 :(得分:5)

简答:

长答案:

您正在写出数据的二进制表示 这不能跨平台或操作系统甚至编译器移植。

你写的所有对象都有可以改变的东西:

int:        size and endianess.
double:     size and representation.
structure:  Each member has to be looked at individually.
            The structure itself may be padded different on different compilers.
            Or even the same compiler with different flags.
pointers:   Are meaningless even across processes on the same machine.
            All pointers have to be converted into something meaningful like
            a named object that is provided separately. The transport will then
            have to convert named objects into pointers at the transport layer
            at the destination.

您有两个主要选择:

  • 流式传输数据 这基本上是将结构转换为文本表示并发送字符串。对于小对象,API结构,这是进行跨平台/语言通信的当前标准方法(尽管数据通常以某种格式包装,如XML或Json)。
  • 转换为网络中性二进制格式
    为此,我们有htonl()和函数族()用于转换整数。双打更难,通常转换成两个整数(值取决于精度要求)。字符串被转换为长度,后跟一系列字符等。然后将每个字符串单独写入流。这可以比流式传输更紧凑(因此效率更高)。不利的一面是,您将两端紧密耦合到一种非常特定的格式,从而使解决方案特别脆弱,在错误情况下更难纠正。

答案 1 :(得分:4)

fwritefread非常便携,但您会遇到sizeof(double)之类的问题,这些问题可能因系统而异。确保您编写的每个二进制字段都具有不依赖于编译器或操作系统的已定义大小 - 您可以通过使用明确指定其大小的类型(例如uint32_t)来实现此目的。

您还必须担心字节序,但您可以使用宏ntohntohlhtonhtonl来为您交换字节顺序,以及它们应被定义为适用于您编译它们的任何系统。

答案 2 :(得分:1)

此文件绝对不可移植。这就是htons之类的东西存在的原因。您必须确保您的文件格式非常清楚地指定大小和endianness。由于个别类型不可移植,因此结构不是(甚至不考虑struct packing)。

答案 3 :(得分:1)

如果你正在编写结构,并且它们不是自包含的(意味着它们有指针,子结构),那么使用某种序列化库会更好。有Boost Serilization库,它采用面向对象的方法。输出可以很容易地从文本切换到二进制,这使调试更容易。

还有HDF5(分层数据格式),这是一组常规用于某些不寻常硬件(不是标准x86)的科学计算的库。我从来没有用过这个,所以我不能说它是多么容易使用,但会处理大量的数据集(多个TB)。

答案 4 :(得分:0)

您忘记了Windows假设文件写入处于文本模式,因此您需要将第二个参数中的“w”更改为“wb”以进行fwrite()