字节序是否会影响写入奇数字节
Does endianness affect writing an odd number of bytes?
假设您有一个uint64_t bytes
,并且您知道您只需要7个字节,因为您存储的整数不会超过7个字节的限制。
在编写文件时,您可以执行类似的操作
std::ofstream fout(fileName);
fout.write((char *)&bytes, 7);
仅写入7个字节。
我想弄清楚的问题是,系统的端序是否会影响写入文件的字节数。我知道端序会影响字节的写入顺序,但它也会影响写入的字节吗?(仅适用于写入的字节数少于整数通常的字节数的情况。)
例如,在little-endian系统上,前7个字节从LSB开始写入文件。在big-endian系统中,文件中写入了什么?
换句话说,在小端序系统中,MSB(第8个字节)不会写入文件。在big-endian系统上,我们能期待同样的行为吗?
Endianess只影响(16,32,64)int
的写入方式。如果您正在写入字节,(根据您的情况)它们将以与您执行操作完全相同的顺序写入。
例如,这种书写会受到endianes:的影响
std::ofstream fout(fileName);
int i = 67;
fout.write((char *)&i, sizeof(int));
uint64_t bytes = ...;
fout.write((char *)&bytes, 7);
这将从&字节。LE和BE系统内存中八个字节的布局方式不同(假设变量位于地址0xff00
):
0xff00 0xff01 0xff02 0xff03 0xff04 0xff05 0xff06 0xff07
LE: [byte 0 (LSB!)][byte 1][byte 2][byte 3][byte 4][byte 5][byte 6][byte 7 (MSB)]
BE: [byte 7 (MSB!)][byte 6][byte 5][byte 4][byte 3][byte 2][byte 1][byte 0 (LSB)]
如果强制转换为char*,起始地址(0xff00
)不会更改,并且您将打印出该地址的字节加上接下来的六个字节–在这两种情况下(LE和BE),地址0xff07
将不会被打印。现在,如果你看看我上面的内存表,很明显,在be系统上,你在存储MSB时丢失了LSB,而MSB不携带信息。。。
在BE系统上,您可以改为编写fout.write((char *)&bytes + 1, 7);
。不过,请注意,这还留下了一个可移植性问题:
fout.write((char *)&bytes + isBE(), 7);
// ^ giving true/false, i. e. 1 or 0
// (such function/test existing is an assumption!)
这样,BE系统写入的数据在读回时会被LE系统误解,反之亦然。安全版本将分解每个字节,就像geza在回答中所做的那样。为了避免多个系统调用,您可以将值分解为一个数组并打印出该数组。
如果在linux/BSD上,也有一个不错的替代方案:
bytes = htole64(bytes); // will likely result in a no-op on LE system...
fout.write((char *)&bytes, 7);
我想弄清楚的问题是系统的端序是否会影响写入文件的字节。
是的,它会影响写入文件的字节数。
例如,在little-endian系统上,前7个字节从LSB开始写入文件。在big-endian系统中,文件中写入了什么?
前7个字节写入文件。但这一次,从MSB开始。因此,最后,最低的字节是而不是写入文件中,因为在big-endian系统中,最后一个字节是最低的字节。
所以,这不是你想要的,因为你失去了信息。
一个简单的解决方案是将uint64_t
转换为little-endian,并写入转换后的值。或者,只需以小端序系统写入的方式逐字节写入值:
uint64_t x = ...;
write_byte(uint8_t(x));
write_byte(uint8_t(x>>8));
write_byte(uint8_t(x>>16));
// you get the idea how to write the remaining bytes
- 从不同线程使用int64的不同字节安全吗
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 如何从保存在 Java 中C++的字节数组中读取数字?
- 我想将四个字节合并为一个数字以进行串行传输
- 有没有办法将字节数组转换为C++中的数字
- 如何将一个数字(大于8个字节)从字符阵列转换为其ASCII表示
- 使用位操作将8字节数字中的每个字节中的一位转换为单个字节
- C++两个字节上写一个数字
- 显示非常大的数字,用字节[]表示
- 一次打印 2 个字节的十六进制数字
- Int 到字节数组和返回不会在大数字上给出相同的值
- 取消引用类型punned指针将打破严格的混叠规则:将字节数组转换为数字
- 如何在c++中从字节数组中的整数转换数字
- 字节数组为十六进制数字(0到9和A到F)
- 数字的字节表示
- 如何在 2 字节字符中存储 1 个数字
- 8 字节如何容纳 302 个十进制数字?(欧拉挑战16)
- 将字节转换为两位十六进制数字
- 如何将数字转换为字节数组(按位端顺序)