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

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

本文关键字:读取 二进制 C++ 64位 32位      更新时间:2023-10-16

如果您有二进制输出流,并将整数写入32位Windows计算机上的文件。那么,你能在64位Windows计算机上从同一个文件中读取相同的整数吗?

我的猜测是。由于32位计算机上的整数是4个字节,而64位计算机中的整数是8个字节。

以下代码也是如此,而文件必须能够从64位和32位计算机读取和写入,无论操作系统、计算机体系结构和数据类型如何。如果不是,当文件必须是二进制形式时,如何才能做到这一点。

写作

std::ofstream ofs("example.bin", std::ios::binary);
int i = 128;
ofs.write((char*) (&i), sizeof(i));
ofs.close();

阅读

std::ifstream ifs("example.bin", std::ios::binary);
int i = 0;
ifs.read((char*) (&i), sizeof(i));
ifs.close();

虽然int几乎所有现代平台(32位和64位)上都是4字节,但其大小无法保证。因此,为了将数据序列化到文件或其他二进制流中,您应该更喜欢在C++11中引入的头<cstdint>中的固定宽度整数类型(一些编译器在C++03中支持它):

#include <cstdint>
...
int32_t i = 128;
ofs.write((char*)(&i), sizeof(i));
...

另一种选择是强制特定类型具有特定大小,例如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));
...

考虑到我们有如上所述的固定宽度整数,这听起来很愚蠢,但如果你想将你所做假设的整个结构存储在某个库的某个版本中,这可能会很有用。示例:glm中的vec4被记录为包含四个浮点,因此在序列化此结构时,最好静态检查它,以便捕捉未来的库更改(不太可能,但可能)。

然而,需要考虑的另一件非常重要的事情是整型的endianes,它在不同的平台之间有所不同现代x86桌面平台的大多数编译器都使用little-endian作为整型,所以我更喜欢这种二进制文件格式;但是,如果平台使用big-endian,则需要对其进行转换(颠倒字节顺序)。

在C++中无法保证int的大小。你所知道的是,它至少和短int一样大,不比长int大。编译器可以在这些约束条件下自由选择合适的大小。虽然大多数人会选择32位作为int的大小,但有些人不会。

如果您知道您的类型总是32位,那么您可以使用int32_t类型。

include <stdint.h>

以获得此类型。