简体   繁体   English

C ++二进制写入/读取32位到/从64位

[英]C++ Binary Writing/Reading on 32bit to/from 64bit

If you have a binary output stream , and write integers to a file on a 32-bit Windows computer. 如果您有二进制输出流 ,并将整数写入32位Windows计算机上的文件。 Would you then be able to read the same integers from that same file on a 64-bit Windows computer? 那么您是否能够在64位Windows计算机上从同一文件中读取相同的整数?

My guess would be no . 我的猜测是否定的 Since an integer on a 32-bit computer is 4 bytes, where an integer on a 64-bit computer is 8 bytes. 由于32位计算机上的整数是4个字节,因此64位计算机上的整数是8个字节。

So does the following code work, while the files have to be able to be read and written from and by both 64-bit and 32-bit computers, no matter the OS, computer architecture and data type. 以下代码也是如此,而无论操作系统,计算机体系结构和数据类型如何,都必须能够从64位和32位计算机读取和写入文件。 If not how would one be able to do that, while the files have to be in binary form. 如果不是,那么如何才能做到这一点,而文件必须是二进制形式。

Writing 写作

std::ofstream ofs("example.bin", std::ios::binary);

int i = 128;
ofs.write((char*) (&i), sizeof(i));

ofs.close();

Reading

std::ifstream ifs("example.bin", std::ios::binary);

int i = 0;
ifs.read((char*) (&i), sizeof(i));

ifs.close();

While int is 4 bytes on almost all modern platforms (32bit and 64bit), there is no guarantee for its size. 虽然int几乎所有现代平台(32位和64位)上都是4个字节,但不能保证其大小。 So for serializing data into a file or other binary streams, you should prefer fixed width integer types from the header <cstdint> which were introduced in C++11 (some compilers support it in C++03): 因此,为了将数据序列化到文件或其他二进制流中,您应该更喜欢C ++ 11中引入的头文件<cstdint>固定宽度整数类型(某些编译器在C ++ 03中支持它):

#include <cstdint>

...
int32_t i = 128;
ofs.write((char*)(&i), sizeof(i));
...

Another option is to enforce a certain type to have a certain size, eg int to have size 4. To make sure your program won't compile if this was not true, use static_assert : 另一种选择是强制某种类型具有一定的大小,例如int以具有大小4.为了确保你的程序不能编译,如果不是这样,请使用static_assert

...
int i = 128;
static_assert(sizeof(i) == 4, "Field i has to have size 4.");
ofs.write((char*)(&i), sizeof(i));
...

While this sounds stupid considering we have fixed width integers as above, this might be useful if you want to store a whole struct of which you made assumptions in a certain version of some library. 虽然这听起来很愚蠢,考虑到我们如上所述固定宽度整数,但如果你想存储一个你在某个库的某个版本中做出假设的整个结构,这可能会很有用。 Example: vec4 from glm is documented to contain four floats, so when serializing this struct, it's good to check this statically in order to catch future library changes (unlikely but possible). 示例:来自glm vec4被记录为包含四个浮点数,因此在序列化此结构时,最好静态地检查它以便捕获将来的库更改(不太可能但可能)。

Another very important thing to consider however is the endianess of integral types, which varies among platforms. 然而,另一个非常重要的考虑因素是整体类型的结束,这些类型因平台而异。 Most compilers for modern x86 desktop platforms use little endian for integral types, so I'd prefer this for your binary file format; 现代x86桌面平台的大多数编译器对整数类型使用小端,所以我更喜欢这种二进制文件格式; but if the platform uses big endian you need to convert it (reverse the byte order). 但如果平台使用大端,则需要转换它(反转字节顺序)。

There's no guarantee for the size of an int in C++. 不能保证C ++中int的大小。 All you know is that it will be at least as big as a short int and no larger than a long int. 你要知道的是,它至少与short int一样大,并且不大于long int。 The compiler is free to choose an appropriate size within these constraints. 编译器可以在这些约束中自由选择合适的大小。 While most will choose 32-bits as the size of an int, some won't. 虽然大多数人会选择32位作为int的大小,但有些人不会。

If you know your type is always 32-bits then you can use the int32_t type. 如果您知道您的类型总是32位,那么您可以使用int32_t类型。

include <stdint.h>

to get this type. 得到这种类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM